auser-poolparty 1.3.13 → 1.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/VERSION.yml +1 -1
  2. data/bin/cloud-compile +1 -0
  3. data/lib/cloud_providers/cloud_provider.rb +9 -0
  4. data/lib/cloud_providers/connections.rb +3 -2
  5. data/lib/cloud_providers/ec2/ec2.rb +19 -5
  6. data/lib/cloud_providers/ec2/ec2_helpers.rb +60 -5
  7. data/lib/cloud_providers/vmware/vmware.rb +3 -0
  8. data/lib/dependency_resolvers/base.rb +2 -9
  9. data/lib/poolparty/base.rb +2 -2
  10. data/lib/poolparty/cloud.rb +6 -4
  11. data/lib/poolparty/installers/ec2.rb +2 -14
  12. data/lib/poolparty/plugins/apache.rb +30 -9
  13. data/lib/poolparty/plugins/apache2/passenger_site.rb +1 -1
  14. data/lib/poolparty/pool.rb +2 -2
  15. data/lib/poolparty/resource.rb +16 -13
  16. data/lib/provision/bootstrap_scripts/build_centos.sh +2 -0
  17. data/lib/provision/bootstrap_scripts/build_ubuntu.sh +1 -0
  18. data/test/fixtures/clouds/fake_clouds.rb +2 -2
  19. data/test/fixtures/clouds/simple_cloud.rb +1 -1
  20. data/test/fixtures/resources/fake_subclassed_plugin.rb +19 -0
  21. data/test/lib/cloud_providers/ec2/ec2_instance_test.rb +17 -8
  22. data/test/lib/cloud_providers/ec2/ec2_test.rb +15 -11
  23. data/test/lib/dependency_resolvers/base_test.rb +1 -1
  24. data/test/lib/dependency_resolvers/chef/resources/remote_directory_test.rb +2 -2
  25. data/test/lib/dependency_resolvers/chef/resources/remote_file_test.rb +1 -1
  26. data/test/lib/dependency_resolvers/chef_test.rb +3 -3
  27. data/test/lib/poolparty/cloud_test.rb +47 -32
  28. data/test/lib/poolparty/pool_test.rb +3 -3
  29. data/test/lib/poolparty/resource_test.rb +14 -2
  30. data/test/lib/poolparty/resources/directory_test.rb +1 -1
  31. data/test/lib/poolparty/resources/file_test.rb +1 -1
  32. data/test/lib/poolparty/resources/user_test.rb +1 -1
  33. data/test/lib/provision/bootstrapper_test.rb +0 -25
  34. data/test/test_helper.rb +0 -1
  35. metadata +5 -3
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 3
3
- :patch: 13
3
+ :patch: 14
4
4
  :major: 1
data/bin/cloud-compile CHANGED
@@ -19,6 +19,7 @@ EOS
19
19
  run do |command|
20
20
 
21
21
  @loaded_clouds.each do |cld|
22
+ ENV["POOLPARTY_NO_VALIDATION"] = "true"
22
23
 
23
24
  cld.compile
24
25
 
@@ -81,5 +81,14 @@ module CloudProviders
81
81
  results.select_with_hash(hsh)
82
82
  end
83
83
 
84
+ def before_compile(cld)
85
+ end
86
+
87
+ def after_compile(cld)
88
+ end
89
+
90
+
91
+
92
+
84
93
  end
85
94
  end
@@ -41,10 +41,11 @@ module CloudProviders
41
41
  # {'-i'=>'keyfile, '-l' => 'fred' } would become
42
42
  # "-i keyfile -o StrictHostKeyChecking=no -i keypair.to_s -l fred"
43
43
  def ssh_options(opts={})
44
- o = {"-i" => keypair.full_filepath,
44
+ return @ssh_options if @ssh_options && opts.empty?
45
+ ssh_options = {"-i" => keypair.full_filepath,
45
46
  "-o" =>"StrictHostKeyChecking=no"
46
47
  }.merge(opts)
47
- o.collect{ |k,v| "#{k} #{v}"}.join(' ')
48
+ @ssh_options = ssh_options.collect{ |k,v| "#{k} #{v}"}.join(' ')
48
49
  end
49
50
 
50
51
  def rsync( opts={} )
@@ -19,12 +19,15 @@ using :provider_name
19
19
  EOM
20
20
  end
21
21
 
22
+ require "#{File.dirname(__FILE__)}/ec2_helpers"
22
23
  require "#{File.dirname(__FILE__)}/ec2_response"
23
24
  require "#{File.dirname(__FILE__)}/ec2_instance"
24
25
 
25
26
  module CloudProviders
26
27
  class Ec2 < CloudProvider
27
28
 
29
+ include CloudProviders::Ec2Helpers
30
+
28
31
  # Set the aws keys from the environment, or load from /etc/poolparty/env.yml if the environment variable is not set
29
32
  def self.default_access_key
30
33
  ENV['EC2_ACCESS_KEY'] || load_keys_from_file[:access_key]
@@ -88,8 +91,8 @@ module CloudProviders
88
91
  :ramdisk_id => nil,
89
92
  :availability_zone => nil,
90
93
  :block_device_mappings => nil,
91
- :elastic_ips => nil, # An array of the elastic ips
92
- :ebs_volume_id => nil # The volume id of an ebs volume # TODO: ensure this is consistent with :block_device_mappings
94
+ :elastic_ips => [], # An array of the elastic ips
95
+ :ebs_volumes => [] # The volume id of an ebs volume # TODO: ensure this is consistent with :block_device_mappings
93
96
  })
94
97
 
95
98
 
@@ -99,11 +102,12 @@ module CloudProviders
99
102
 
100
103
  # Start a new instance with the given options
101
104
  def run_instance(o={})
105
+ number_of_instances = o[:number_of_instances] || 1
102
106
  set_vars_from_options o
103
107
  raise StandardError.new("You must pass a keypair to launch an instance, or else you will not be able to login. options = #{o.inspect}") if !keypair_name
104
108
  response_array = ec2(o).run_instances(image_id,
105
109
  min_count,
106
- max_count,
110
+ number_of_instances,
107
111
  security_group,
108
112
  keypair.basename,
109
113
  user_data,
@@ -114,10 +118,12 @@ module CloudProviders
114
118
  availability_zone,
115
119
  block_device_mappings
116
120
  )
117
- instances = response_array .collect do |aws_response_hash|
121
+ instances = response_array.collect do |aws_response_hash|
118
122
  Ec2Instance.new( Ec2Response.pp_format(aws_response_hash).merge(o) )
119
123
  end
120
- #FIXME: This needs to deal with the case when an array is returned if max_instances > 1
124
+
125
+ after_run_instance(instances)
126
+
121
127
  instances.first
122
128
  end
123
129
 
@@ -162,6 +168,14 @@ module CloudProviders
162
168
  save_aws_env_to_yml(cld.tmp_path/"etc"/"poolparty"/"env.yml") rescue nil
163
169
  end
164
170
 
171
+ # Run after all the instances are run
172
+ def after_run_instance(instances_list)
173
+ instances_list.each do |inst|
174
+ associate_address(inst.instance_id) if next_unused_elastic_ip
175
+ attach_volume(inst.instance_id) if next_unused_volume
176
+ end
177
+ end
178
+
165
179
  # Read yaml file and use it to set environment variables and local variables.
166
180
  def set_aws_env_from_yml_file(filename='/etc/poolparty/env.yml')
167
181
  aws = self.class.load_keys_from_file(filename)
@@ -1,12 +1,57 @@
1
1
  module CloudProviders
2
2
  module Ec2Helpers
3
3
 
4
+ # VOLUMES
5
+ def attach_volume(instance_id, volume_id=next_unused_volume, device="/dev/sdh")
6
+ ec2.attach_volume(volume_id, instance_id, device)
7
+ end
8
+
9
+ def next_unused_volume
10
+ if all_volumes.empty?
11
+ nil
12
+ else
13
+ available_volumes.first
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def all_volumes
20
+ ebs_volumes.empty? ? [] : ec2.describe_volumes.select {|v| ebs_volumes.include?(v[:aws_id]) }
21
+ end
22
+
23
+ def available_volumes
24
+ all_volumes.select {|v| v[:aws_status] == 'available' }
25
+ end
26
+
27
+ def unavailable_volumes
28
+ all_volumes.reject {|v| available_volumes.include?(v) }
29
+ end
30
+
31
+ public
32
+
33
+ # SECURITY GROUPS
34
+ def security_groups(list=[])
35
+ ec2.describe_security_groups(list)
36
+ end
37
+
38
+ public
39
+
40
+ # ELASTIC IPS
41
+
4
42
  # Associate an address with the instance using ec2
5
43
  # Get the next_unused_elastic_ip
6
44
  # and if there is one, associate the instance to the
7
45
  # public ip
8
- def associate_address()
9
- raise StandardError.new('Not Implemented Yet')
46
+ def associate_address(instance_id)
47
+ new_ip = next_unused_elastic_ip
48
+ ec2.associate_address(instance_id, new_ip)
49
+ loop do
50
+ if describe_instance(:instance_id => instance_id).public_ip == new_ip
51
+ return new_ip
52
+ end
53
+ sleep 1
54
+ end
10
55
  end
11
56
 
12
57
  # Get the next usable elastic ip
@@ -17,13 +62,23 @@ module CloudProviders
17
62
  # intersection of the unused ips and those, find the first one available
18
63
  # and return that.
19
64
  def next_unused_elastic_ip
20
- raise StandardError.new('Not Implemented Yet')
21
- if elastic_ips.empty?
65
+ if unusued_elastic_ips.empty?
22
66
  nil
23
67
  else
68
+ unusued_elastic_ips.first
24
69
  end
25
70
  end
26
-
71
+
72
+ private
73
+
74
+ def all_elastic_ips
75
+ elastic_ips.empty? ? [] : ec2.describe_addresses & elastic_ips
76
+ end
77
+
78
+ def unusued_elastic_ips
79
+ all_elastic_ips.select {|i| i[:instance_id] == nil }
80
+ end
81
+
27
82
  # Help create a keypair for the cloud
28
83
  # This is a helper to create the keypair and add them to the cloud for you
29
84
  # def create_keypair
@@ -122,6 +122,9 @@ module CloudProviders
122
122
  end
123
123
  @vmx_file = "'#{o}'"
124
124
  end
125
+
126
+ def before_compile(args); end
127
+ def after_compile(args); end
125
128
 
126
129
  end
127
130
  end
@@ -89,14 +89,7 @@ module DependencyResolvers
89
89
  "#{obj.to_i}"
90
90
  end
91
91
  when String
92
- case obj
93
- when /^\d{4}$/
94
- "#{obj}"
95
- when /^\d{3}$/
96
- "0#{obj}"
97
- else
98
- "\"#{obj}\""
99
- end
92
+ "\"#{obj}\""
100
93
  when Proc
101
94
  obj.call # eh
102
95
  when Array
@@ -119,4 +112,4 @@ module DependencyResolvers
119
112
 
120
113
  end
121
114
 
122
- end
115
+ end
@@ -157,12 +157,12 @@ module PoolParty
157
157
  deps_array.each do |dep_name|
158
158
  dep = get_resource(dep_type, dep_name)
159
159
  raise PoolPartyError.create("ResourceNotFound", "A resource required for #{resource.has_method_name}(#{resource.name}) was not found: #{dep_type}(#{dep_name}). Please make sure you've specified this in your configuration.") unless dep
160
- result.add_edge!(dep, resource, dep.name) unless result.edge?(dep, resource)
160
+ result.add_edge!(dep, resource, dep.name) unless result.edge?(dep, resource) or result.edge?(resource, dep)
161
161
  end
162
162
  end
163
163
 
164
164
  if on
165
- result.add_edge!(resource, on, resource.name) unless result.edge?(resource, on)
165
+ result.add_edge!(resource, on, resource.name) unless result.edge?(resource, on) or result.edge?(on, resource)
166
166
  else
167
167
  result.add_vertex!(resource)
168
168
  end
@@ -14,7 +14,8 @@ module PoolParty
14
14
  :cloud_provider_name => :ec2,
15
15
  :dependency_resolver_name => nil,
16
16
  :os => nil,
17
- :bootstrap_script => nil
17
+ :bootstrap_script => nil,
18
+ :ssh_options => {}
18
19
  )
19
20
 
20
21
  # Define what gets run on the callbacks
@@ -29,7 +30,7 @@ module PoolParty
29
30
  def before_compile
30
31
  add_monitoring_stack_if_needed
31
32
 
32
- validate_all_resources
33
+ validate_all_resources unless ENV["POOLPARTY_NO_VALIDATION"]
33
34
  end
34
35
 
35
36
  # Freeze the cloud_name so we can't modify it at all, set the plugin_directory
@@ -59,7 +60,8 @@ module PoolParty
59
60
  def using(provider_symbol, o={}, &block)
60
61
  return @cloud_provider if @cloud_provider
61
62
  self.cloud_provider_name = provider_symbol
62
- cloud_provider(o, &block)
63
+ cloud_provider(ssh_options.merge(o), &block)
64
+ cloud_provider.keypair(keypair)
63
65
  end
64
66
 
65
67
  # Cloud provider methods
@@ -79,7 +81,7 @@ module PoolParty
79
81
  return @cloud_provider if @cloud_provider
80
82
  klass_name = "CloudProviders::#{cloud_provider_name}".classify
81
83
  if provider_klass = CloudProviders.all.detect {|k| k.to_s == klass_name }
82
- opts.merge!(:cloud => self, :keypair_name => self.keypair.basename)
84
+ opts.merge!(:cloud => self, :keypair_name => self.keypair.full_filepath)
83
85
  @cloud_provider = provider_klass.new(dsl_options.merge(opts), &block)
84
86
  else
85
87
  raise PoolParty::PoolPartyError.create("UnknownCloudProviderError", "Unknown cloud_provider: #{cloud_provider_name}")
@@ -4,7 +4,7 @@ module PoolParty
4
4
 
5
5
  def steps
6
6
  [
7
- :find_ec2_directory, :ask_for_access_key, :ask_for_private_access_key,
7
+ :ask_for_ec2_directory, :ask_for_access_key, :ask_for_private_access_key,
8
8
  :show_env_setup
9
9
  ]
10
10
  end
@@ -16,19 +16,7 @@ module PoolParty
16
16
  def self.description
17
17
  "Ec2 installer"
18
18
  end
19
-
20
- def find_ec2_directory
21
- msg = "We found the following vmware files in the default vmware directory.\nChoose one of these to use as your vmrun file or select other\n<line>"
22
-
23
- directories = {}
24
- default_ec2_directories.each_with_index do |file,idx|
25
- directories.merge!(idx+1 => file)
26
- end
27
-
28
- base = choose(msg, directories)
29
- @ec2_directory = base == :other ? ask_for_ec2_directory : base
30
- end
31
-
19
+
32
20
  def ask_for_access_key
33
21
  access_key_help =<<-EOV
34
22
  EC2 uses an access key to identify you and allows you to start and stop instances.
@@ -7,7 +7,7 @@ module PoolParty
7
7
  default_options :port => 80,
8
8
  :www_user => 'www-data',
9
9
  :www_dir => "/var/www",
10
- :passenger_version => "2.2.4"
10
+ :passenger_version => "2.2.5"
11
11
 
12
12
  def before_load
13
13
  installed_as_worker
@@ -39,6 +39,13 @@ module PoolParty
39
39
  def install_passenger
40
40
  enable_passenger
41
41
  end
42
+
43
+
44
+ # LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.5/ext/apache2/mod_passenger.so
45
+ # PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.5
46
+ # PassengerRuby /usr/bin/ruby1.8
47
+ #
48
+ # creating this thing below may not be being run b/c it checks for the passenger.conf which isn't really a good test
42
49
 
43
50
  def enable_passenger
44
51
  unless @enable_passenger
@@ -46,7 +53,7 @@ module PoolParty
46
53
  has_package "build-essential"
47
54
  has_package "apache2-prefork-dev"
48
55
  has_gem_package "fastthread"
49
- has_gem_package "passenger"
56
+ has_gem_package "passenger", :version => passenger_version
50
57
  passenger_configs
51
58
 
52
59
  has_exec "install_passenger_script" do
@@ -55,8 +62,8 @@ module PoolParty
55
62
  requires get_exec("restart-apache2")
56
63
  requires get_package("apache2")
57
64
  requires get_gem_package("passenger")
58
- not_if "test -f /etc/apache2/mods-available/passenger.conf && test -s /etc/apache2/mods-available/passenger.conf "
59
- creates lambda { "@node[:apache][:passenger_module_path]" }
65
+ not_if "test -e \#{node[:passenger_site][:passenger_module_path]}"
66
+ # creates lambda { "passenger_site[:passenger_module_path]" }
60
67
  end
61
68
 
62
69
  @enable_passenger = true
@@ -65,15 +72,26 @@ module PoolParty
65
72
 
66
73
  def passenger_configs
67
74
  unless @passenger_configs
75
+
76
+ # requires doesn't work for has_variable?
68
77
 
78
+ # has_variable("passenger_version", passenger_version)
79
+ # has_variable("passenger_root_path", "\#{languages[:ruby][:gems_dir]}/gems/passenger-#{passenger_version}",
80
+ # :requires => get_variable("passenger_version"))
81
+ # has_variable("passenger_module_path", "\#{passenger_site[:passenger_root_path]}/ext/apache2/mod_passenger.so",
82
+ # :requires => get_variable("passenger_root_path"))
83
+
69
84
  has_variable("passenger_version", passenger_version)
70
- has_variable("passenger_root_path", "\#{languages[:ruby][:gems_dir]}/gems/passenger-#{passenger_version}")
71
- has_variable("passenger_module_path", "\#{passenger_site[:passenger_root_path]}/ext/apache2/mod_passenger.so")
85
+ has_variable("passenger_root_path", "\#{languages[:ruby][:gems_dir]}/gems/passenger-#{passenger_version}",
86
+ :requires => get_variable("passenger_version"))
87
+ has_variable("passenger_module_path", "\#{languages[:ruby][:gems_dir]}/gems/passenger-#{passenger_version}/ext/apache2/mod_passenger.so",
88
+ :requires => get_variable("passenger_root_path"))
72
89
 
73
90
  has_file(:name => "/etc/apache2/mods-available/passenger.load") do
74
91
  content <<-eof
75
92
  LoadModule passenger_module <%= @node[:passenger_site][:passenger_module_path] %>
76
93
  eof
94
+ requires get_exec("install_passenger_script")
77
95
  end
78
96
 
79
97
  has_file(:name => "/etc/apache2/mods-available/passenger.conf") do
@@ -81,9 +99,10 @@ LoadModule passenger_module <%= @node[:passenger_site][:passenger_module_path] %
81
99
  PassengerRoot <%= @node[:passenger_site][:passenger_root_path] %>
82
100
  PassengerRuby <%= @node[:languages][:ruby][:ruby_bin] %>
83
101
  eof
102
+ requires get_exec("install_passenger_script")
84
103
  end
85
104
 
86
- present_apache_module(:passenger)
105
+ present_apache_module(:passenger, {:requires => get_file("/etc/apache2/mods-available/passenger.load")})
87
106
  @passenger_configs = true
88
107
  end
89
108
  end
@@ -159,9 +178,9 @@ PassengerRuby <%= @node[:languages][:ruby][:ruby_bin] %>
159
178
  def install_site(name, opts={})
160
179
  sitename = name
161
180
 
162
- opts.merge!(:name => "/etc/apache2/sites-available/#{sitename}")
181
+ opts.merge!(:name => "/etc/apache2/sites-available/#{sitename}", :requires => get_package("apache2"))
163
182
  has_directory(:name => "/etc/apache2/sites-available")
164
- has_file(opts) unless opts[:no_file]
183
+ has_file(opts, :requires => get_package("apache2")) unless opts[:no_file]
165
184
  has_exec(:name => "/usr/sbin/a2ensite #{sitename}") do
166
185
  notifies get_exec("reload-apache2"), :run
167
186
  requires get_exec("reload-apache2")
@@ -175,12 +194,14 @@ PassengerRuby <%= @node[:languages][:ruby][:ruby_bin] %>
175
194
  end
176
195
 
177
196
  def present_apache_module(*names)
197
+ opts = names.pop if names.last.kind_of?(::Hash)
178
198
  names.each do |name|
179
199
  has_exec(:name => "mod-#{name}", :command => "/usr/sbin/a2enmod #{name}") do
180
200
  not_if "/bin/sh -c \'[ -L /etc/apache2/mods-enabled/#{name}.load ] && [ /etc/apache2/mods-enabled/#{name}.load -ef /etc/apache2/mods-available/#{name}.load ]\'"
181
201
  requires get_package("apache2")
182
202
  notifies get_exec("force-reload-apache2"), :run
183
203
  requires get_exec("force-reload-apache2")
204
+ requires opts[:requires] if opts && opts[:requires]
184
205
  end
185
206
  end
186
207
  end
@@ -34,7 +34,7 @@ module PoolParty
34
34
  # setup an initial symlink so apache will start even if there have not been any deploys yet
35
35
  #has_site_directory "releases/initial/public"
36
36
  #FIXME the following line is chef specific. It will fail with puppet
37
- has_link(:target_file => "#{dir}/#{name}/current", :to => "#{dir}/#{name}/releases/initial")
37
+ has_link(:target_file => "#{dir}/#{name}/current", :to => "#{dir}/#{name}/releases/initial", :requires => get_directory(site_directory))
38
38
  end
39
39
  log_dir = "#{site_directory}/shared/log"
40
40
  appended_path "current"
@@ -97,7 +97,7 @@ module PoolParty
97
97
  end
98
98
 
99
99
  def self.clouds_dot_rb_dir(n=nil)
100
- File.dirname(self.clouds_dot_rb_file) if self.clouds_dot_rb_file
100
+ self.clouds_dot_rb_file ? File.dirname(self.clouds_dot_rb_file) : "./"
101
101
  end
102
102
 
103
103
  # Load the default clouds.rb file
@@ -155,7 +155,7 @@ module PoolParty
155
155
  $:.unshift("#{File.dirname(filepath)}/lib")
156
156
  $:.unshift("#{File.dirname(filepath)}/plugins")
157
157
 
158
- Dir["#{File.dirname(filepath)}/lib/*"].each {|lib_path| require lib_path }
158
+ Dir["#{File.dirname(filepath)}/lib/*.rb"].each {|lib_path| require lib_path }
159
159
  Dir["#{File.dirname(filepath)}/plugins/*"].each do |plugin_path|
160
160
  if File.directory?(plugin_path)
161
161
  $:.unshift(plugin_path)
@@ -15,6 +15,7 @@ module PoolParty
15
15
  def initialize(opts={}, extra_opts={}, exists=true, &block)
16
16
  @exists ||= exists
17
17
  super(opts, extra_opts, &block)
18
+ after_loaded_requires_parent
18
19
  valid?
19
20
  end
20
21
 
@@ -69,6 +70,11 @@ module PoolParty
69
70
  other_resources_obj.each do |obj|
70
71
  requires(obj)
71
72
  end
73
+ else
74
+ # When is an object
75
+ # k = other_resources_obj.has_method_name
76
+ # dependencies[k] ||= []
77
+ # dependencies[k] << other_resources_obj.name
72
78
  end
73
79
  end
74
80
 
@@ -114,7 +120,7 @@ module PoolParty
114
120
  def after_compile
115
121
  end
116
122
 
117
- def after_loaded
123
+ def after_loaded_requires_parent
118
124
  requires parent if parent && !parent.is_a?(PoolParty::Cloud) && !parent.is_a?(PoolParty::Pool)
119
125
  end
120
126
 
@@ -162,8 +168,8 @@ module PoolParty
162
168
  def self.define_resource_methods
163
169
  defined_resources.each do |res|
164
170
  next if res.method_defined?
165
- ddputs "Defining resource: #{res} as #{res.has_method_name}"
166
- define_resource(res)
171
+ ddputs "Defining resource: #{res} as #{res.has_method_name} on #{self}"
172
+ define_resource(res, is_base_resource_class? ? Base : self)
167
173
  res.method_defined!
168
174
  unless res.defined_resources.empty?
169
175
  res.define_resource_methods
@@ -171,10 +177,14 @@ module PoolParty
171
177
  end
172
178
  end
173
179
 
180
+ def self.is_base_resource_class?
181
+ self.to_s == PoolParty::Resource.to_s
182
+ end
183
+
174
184
  # Define the resource on the base class so it's available across all
175
185
  # PoolParty classes that use Base
176
- def self.define_resource(res)
177
- Base.class_eval <<-EOE
186
+ def self.define_resource(res, base_klass=Base)
187
+ base_klass.class_eval <<-EOE
178
188
  def has_#{res.has_method_name}(a={},b={},e=true, &block)
179
189
  obj = #{res}.new(a,b,e,&block)
180
190
  resources << obj
@@ -252,14 +262,7 @@ module PoolParty
252
262
  "#{obj.to_i}"
253
263
  end
254
264
  when String
255
- case obj
256
- when /^\d{4}$/
257
- "#{obj}"
258
- when /^\d{3}$/
259
- "0#{obj}"
260
- else
261
- "\"#{obj}\""
262
- end
265
+ "\"#{obj}\""
263
266
  when Proc
264
267
  obj.call # eh
265
268
  when Array
@@ -4,6 +4,8 @@
4
4
  # Make the /etc/poolparty directory to hold poolparty configuration
5
5
  mkdir -p /etc/poolparty
6
6
  mkdir -p /var/log/poolparty
7
+ mkdir -p /etc/poolparty/keys
8
+
7
9
 
8
10
  # Build the user groups
9
11
  if [ ! "$(egrep "poolparty" /etc/group)" ]; then
@@ -3,6 +3,7 @@
3
3
  # Build the directories
4
4
  # Make the /etc/poolparty directory to hold poolparty configuration
5
5
  mkdir -p /etc/poolparty
6
+ mkdir -p /etc/poolparty/keys
6
7
  mkdir -p /var/log/poolparty
7
8
 
8
9
  # Build the user groups
@@ -1,7 +1,7 @@
1
1
  pool :boxed do
2
2
 
3
- cloud :app do
4
- keypair 'test_key'
3
+ cloud :fake_cloud do
4
+ keypair File.dirname(__FILE__)+"/../keys/test_key"
5
5
  using :ec2 do
6
6
  end
7
7
  end
@@ -4,7 +4,7 @@ pool :poolparty do
4
4
 
5
5
  instances 1
6
6
 
7
- cloud :app do
7
+ cloud :simple_cloud do
8
8
  os :centos
9
9
  keypair File.dirname(__FILE__)+"/../keys/test_key"
10
10
  has_file "/etc/motd", :content => "Simple"
@@ -0,0 +1,19 @@
1
+ module PoolParty
2
+ module Resources
3
+
4
+ class FakeSubclassedPlugin < Resource
5
+
6
+ def self.has_method_name
7
+ "subclassed"
8
+ end
9
+
10
+ def after_loaded
11
+ has_file "/etc/my_configs/special_config" do
12
+ requires get_directory("/etc/my_configs")
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -1,11 +1,20 @@
1
1
  require "#{File.dirname(__FILE__)}/../../../test_helper"
2
2
  require File.dirname(__FILE__)+"/ec2_test.rb"
3
3
 
4
+ stub_keypair_searchable_paths
5
+
4
6
  class Ec2InstanceTest < Test::Unit::TestCase
5
7
  include CloudProviders
6
-
8
+
9
+ def setup
10
+ clear!
11
+ @filepath = fixtures_dir/"clouds/simple_cloud.rb"
12
+ @pool = PoolParty::Pool.load_from_file(@filepath)
13
+ @cloud = @pool.clouds[@pool.clouds.keys.first]
14
+ end
15
+
7
16
  def inst
8
- @inst ||= clouds['app'].describe_instances.first
17
+ @inst ||= @cloud.describe_instances.first
9
18
  end
10
19
 
11
20
  def test_has_cloud_provider
@@ -20,18 +29,18 @@ class Ec2InstanceTest < Test::Unit::TestCase
20
29
  def test_to_s
21
30
  vals = inst.to_s.split("\t")
22
31
  assert_equal 3, vals.size
23
- assert_equal 'app', vals.first
32
+ assert_equal 'simple_cloud', vals.first
24
33
  end
25
34
 
26
35
  def test_has_cloud_set_when_created_from_cloud
27
- assert_equal clouds['app'], clouds['app'].cloud_provider.cloud
28
- assert_equal clouds['app'], inst.cloud
29
- assert_equal 'app', inst.dsl_options[:cloud_name]
30
- assert_equal 'app', inst.to_hash[:cloud_name]
36
+ assert_equal @cloud, @cloud.cloud_provider.cloud
37
+ assert_equal @cloud, inst.cloud
38
+ assert_equal 'simple_cloud', inst.dsl_options[:cloud_name]
39
+ assert_equal 'simple_cloud', inst.to_hash[:cloud_name]
31
40
  end
32
41
 
33
42
  def test_cloud_keypair
34
- assert_equal clouds['app'].keypair.to_s, inst.keypair.to_s
43
+ assert_equal @cloud.keypair.to_s, inst.keypair.to_s
35
44
  end
36
45
 
37
46
  def test_refresh!
@@ -5,7 +5,7 @@ stub_ec2_calls
5
5
  class Ec2ProviderTest < Test::Unit::TestCase
6
6
 
7
7
  def ec2
8
- @ec2 ||= clouds['app'].cloud_provider
8
+ @ec2 ||= @cloud.cloud_provider
9
9
  end
10
10
 
11
11
  def setup
@@ -13,11 +13,15 @@ class Ec2ProviderTest < Test::Unit::TestCase
13
13
  :image_id => "ami-abc123",
14
14
  :keypair => fixtures_dir/'keys/test_key'
15
15
  )
16
+
17
+ @filepath = fixtures_dir/"clouds/simple_cloud.rb"
18
+ @pool = PoolParty::Pool.load_from_file(@filepath)
19
+ @cloud = @pool.clouds[@pool.clouds.keys.first]
16
20
  end
17
21
 
18
22
  def test_setup
19
- assert_not_nil clouds['app']
20
- assert_not_nil clouds['app'].keypair
23
+ assert_not_nil @cloud
24
+ assert_not_nil @cloud.keypair
21
25
  end
22
26
 
23
27
 
@@ -67,9 +71,9 @@ class Ec2ProviderTest < Test::Unit::TestCase
67
71
  end
68
72
 
69
73
  def test_basic_setup
70
- assert_equal :ec2, clouds['app'].cloud_provider_name
71
- assert_instance_of CloudProviders::Ec2, clouds['app'].cloud_provider
72
- assert_instance_of RightAws::Ec2, clouds['app'].cloud_provider.ec2
74
+ assert_equal :ec2, @cloud.cloud_provider_name
75
+ assert_instance_of CloudProviders::Ec2, @cloud.cloud_provider
76
+ assert_instance_of RightAws::Ec2, @cloud.cloud_provider.ec2
73
77
  end
74
78
 
75
79
  def test_that_test_ec2_env_variables_are_set
@@ -89,7 +93,7 @@ class Ec2ProviderTest < Test::Unit::TestCase
89
93
  end
90
94
 
91
95
  def test_cloud_is_set_when_created_from_a_cloud
92
- assert_equal clouds['app'], clouds['app'].cloud_provider.cloud
96
+ assert_equal @cloud, @cloud.cloud_provider.cloud
93
97
  end
94
98
 
95
99
  def test_inherited_default_options
@@ -98,10 +102,10 @@ class Ec2ProviderTest < Test::Unit::TestCase
98
102
  end
99
103
 
100
104
  def amazon?
101
- stub(clouds['app'].cloud_provider).ec2_url {'http://example.com'}
102
- assert clouds['app'].cloud_provider.eucalyptus?
103
- stub(clouds['app'].cloud_provider).ec2_url {'https://ec2.amazonaws.com'}
104
- assert !clouds['app'].cloud_provider.eucalyptus?
105
+ stub(@cloud.cloud_provider).ec2_url {'http://example.com'}
106
+ assert @cloud.cloud_provider.eucalyptus?
107
+ stub(@cloud.cloud_provider).ec2_url {'https://ec2.amazonaws.com'}
108
+ assert !@cloud.cloud_provider.eucalyptus?
105
109
  end
106
110
 
107
111
  def test_aws_hash
@@ -30,7 +30,7 @@ template "/etc/motd" do
30
30
  source "/etc/motd.erb"
31
31
  action :create
32
32
  backup 5
33
- mode 0644
33
+ mode "0644"
34
34
  owner "root"
35
35
  end
36
36
  EOE
@@ -26,10 +26,10 @@ class RemoteDirectoryResourceTest < Test::Unit::TestCase
26
26
  remote_directory "/tmp/remote_something" do
27
27
  source "something"
28
28
  files_backup 10
29
- files_mode 0644
29
+ files_mode "0644"
30
30
  action :create
31
31
  recursive false
32
- mode 0755
32
+ mode "0755"
33
33
  owner "nobody"
34
34
  group "nobody"
35
35
  files_owner "root"
@@ -22,7 +22,7 @@ remote_file "/tmp/testfile" do
22
22
  source "http://www.example.com/tempfiles/testfile"
23
23
  action :create
24
24
  backup 5
25
- mode 0644
25
+ mode "0644"
26
26
  owner "root"
27
27
  checksum "08da002l"
28
28
  end
@@ -54,7 +54,7 @@ class ChefTest < Test::Unit::TestCase
54
54
 
55
55
  def test_compile_to_the_recipes
56
56
  @base.compile_to(@resources[:files], test_dir)
57
- assert_equal "template \"/etc/motd\" do\n source \"/etc/motd.erb\"\n action :create\n backup 5\n mode 0644\n owner \"root\"\nend\n", open(@cookboox_directory/"recipes"/"default.rb").read
57
+ assert_equal "template \"/etc/motd\" do\n source \"/etc/motd.erb\"\n action :create\n backup 5\n mode \"0644\"\n owner \"root\"\nend\n", open(@cookboox_directory/"recipes"/"default.rb").read
58
58
  end
59
59
 
60
60
  def test_compile_the_recipes
@@ -78,14 +78,14 @@ template "/etc/motd" do
78
78
  source "/etc/motd.erb"
79
79
  action :create
80
80
  backup 5
81
- mode 0644
81
+ mode "0644"
82
82
  owner "root"
83
83
  end
84
84
 
85
85
  directory "/etc/poolparty" do
86
86
  action :create
87
87
  recursive true
88
- mode 0644
88
+ mode "0644"
89
89
  owner "root"
90
90
  group "root"
91
91
  end
@@ -34,106 +34,121 @@ class CloudTest < Test::Unit::TestCase
34
34
  end
35
35
 
36
36
  def test_have_a_keypair
37
- assert_not_nil clouds['app'].keypair
38
- assert_equal 'test_key', clouds['app'].keypair.basename
37
+ assert_not_nil @cloud.keypair
38
+ assert_equal 'test_key', @cloud.keypair.basename
39
39
  end
40
40
 
41
41
  def test_set_the_dependency_resolver
42
- clouds['app'].dependency_resolver(:chef)
43
- assert_equal DependencyResolvers::Chef, clouds['app'].dependency_resolver
42
+ @cloud.dependency_resolver(:chef)
43
+ assert_equal DependencyResolvers::Chef, @cloud.dependency_resolver
44
44
  end
45
45
 
46
46
  def test_can_use_basic_resources
47
- clouds['app'].instance_eval do
47
+ @cloud.instance_eval do
48
48
  has_file "/etc/motd"
49
49
  end
50
- assert_equal "/etc/motd", clouds['app'].files.first.name
50
+ assert_equal "/etc/motd", @cloud.files.first.name
51
51
  end
52
52
 
53
53
  def test_have_a_temp_path_of_the_name_as_Default_tmp_path_pool_name_cloud_name
54
- assert_equal PoolParty::Default.tmp_path/"poolparty"/"app", @cloud.tmp_path
54
+ assert_equal PoolParty::Default.tmp_path/"poolparty"/"simple_cloud", @cloud.tmp_path
55
55
  end
56
56
 
57
57
  def test_be_using_ec2_cloud_provider_by_default
58
- assert_equal :ec2, clouds['app'].cloud_provider_name
59
- assert_kind_of ::CloudProviders::Ec2, clouds['app'].cloud_provider
58
+ assert_equal :ec2, @cloud.cloud_provider_name
59
+ assert_kind_of ::CloudProviders::Ec2, @cloud.cloud_provider
60
60
  end
61
61
 
62
62
  def test_raise_if_the_cloud_provider_is_not_a_known_type
63
63
  PoolParty::PoolPartyError.create("UnknownCloudProviderError")
64
64
  assert_raises UnknownCloudProviderError do
65
- clouds["app"].cloud_provider_name = :not_a_cloud_provider
66
- clouds["app"].cloud_provider
65
+ @cloud.cloud_provider_name = :not_a_cloud_provider
66
+ @cloud.cloud_provider
67
67
  end
68
68
  end
69
69
 
70
70
  def test_set_the_cloud_provider_cloud_and_keypair_with_cloud_provider
71
- assert_equal clouds["app"], clouds["app"].cloud_provider.cloud
72
- assert_equal clouds["app"].keypair.basename, clouds["app"].cloud_provider.keypair_name
71
+ assert_equal @cloud, @cloud.cloud_provider.cloud
72
+ assert_equal @cloud.keypair.basename, @cloud.cloud_provider.keypair_name
73
73
  end
74
74
 
75
75
  def test_set_the_cloud_provider_with_a_using_block
76
- clouds["app"].instance_eval do
76
+ @cloud.instance_eval do
77
+ keypair "test_key"
77
78
  using :ec2 do
78
79
  image_id 'emi-39921602'
79
80
  end
80
81
  end
81
- assert_equal :ec2, clouds["app"].cloud_provider_name
82
- assert_equal CloudProviders::Ec2, clouds["app"].cloud_provider.class
83
- assert_equal "emi-39921602", clouds["app"].cloud_provider.image_id
82
+ assert_equal :ec2, @cloud.cloud_provider_name
83
+ assert_equal CloudProviders::Ec2, @cloud.cloud_provider.class
84
+ assert_equal "emi-39921602", @cloud.cloud_provider.image_id
84
85
  end
85
86
 
86
87
  def test_nodes
87
- assert_respond_to clouds['app'], :nodes
88
- assert_respond_to clouds['app'].nodes, :each
89
- assert clouds['app'].nodes.size>1
88
+ assert_respond_to @cloud, :nodes
89
+ assert_respond_to @cloud.nodes, :each
90
+ assert @cloud.nodes.size>1
90
91
  end
91
92
 
92
93
  def test_terminate!
93
- assert clouds['app'].nodes.size > 0
94
- result = clouds['app'].terminate!
94
+ assert @cloud.nodes.size > 0
95
+ result = @cloud.terminate!
95
96
  assert_respond_to result, :each
96
97
  assert_equal 'shutting-down', result.first.status
97
98
  end
98
99
 
99
100
  def test_run
100
101
  # WHAT?
101
- # result = clouds['app'].run('uptime')
102
+ # result = @cloud.run('uptime')
102
103
  # assert_match /uptime/, result["app"]
103
104
  end
104
105
 
105
106
  def test_os
106
- assert_equal :centos, clouds['app'].os
107
+ assert_equal :centos, @cloud.os
107
108
  end
108
109
 
109
110
  def test_expansion
110
111
  #TODO: improve this test
111
- # size = clouds["app"].nodes.size
112
- # assert_equal size+1, clouds["app"].expand.nodes.size
113
- # assert_nothing_raised clouds['app'].expand
112
+ # size = @cloud.nodes.size
113
+ # assert_equal size+1, @cloud.expand.nodes.size
114
+ # assert_nothing_raised @cloud.expand
114
115
  end
115
116
 
116
117
  def test_contract!
117
118
  #TODO: need to better mock the terminate! ec2 call
118
- # size = clouds['app'].nodes.size
119
- # result = clouds['app'].contract!
119
+ # size = @cloud.nodes.size
120
+ # result = @cloud.contract!
120
121
  # assert_equal 'shuttin-down', result.status
121
- # assert_equal size-1, clouds['app'].nodes.size
122
+ # assert_equal size-1, @cloud.nodes.size
122
123
  end
123
124
 
124
125
  def test_change_ssh_port
125
126
  clear!
126
127
  pool "ssh_port" do
127
128
  cloud "babity" do
129
+ keypair "test_key"
128
130
  ssh_port 1922
129
131
  end
130
- cloud "noneity" do
131
- end
132
132
  end
133
133
  assert_equal 1922, clouds["babity"].ssh_port
134
134
  assert_equal 22, clouds["noneity"].ssh_port
135
135
  end
136
136
 
137
+ def test_change_ssh_port
138
+ clear!
139
+ pool "ssher" do
140
+ cloud "custom" do
141
+ keypair "test_key"
142
+ ssh_options("-P" => "1992")
143
+ end
144
+ cloud "noneity" do
145
+ keypair "test_key"
146
+ end
147
+ end
148
+ assert_equal "1992", clouds["custom"].ssh_options["-P"]
149
+ end
150
+
151
+
137
152
  def test_children_getting_parent_options
138
153
  clear!
139
154
  pool "outside" do
@@ -11,9 +11,9 @@ class PoolTest < Test::Unit::TestCase
11
11
  should "load the file with load_from_file on Pool" do
12
12
  PoolParty::Pool.load_from_file(@filepath)
13
13
  assert_equal PoolParty::Pool, pools["poolparty"].class
14
- assert_equal PoolParty::Cloud, pools["poolparty"].clouds["app"].class
15
- assert_equal "test_key", pools["poolparty"].clouds["app"].keypair.basename
16
- assert_equal "/etc/motd", pools["poolparty"].clouds["app"].files.first.name
14
+ assert_equal PoolParty::Cloud, pools["poolparty"].clouds["simple_cloud"].class
15
+ assert_equal "test_key", pools["poolparty"].clouds["simple_cloud"].keypair.basename
16
+ assert_equal "/etc/motd", pools["poolparty"].clouds["simple_cloud"].files.first.name
17
17
  end
18
18
 
19
19
  should "find_and_load_default_clouds_dot_rb in Pool" do
@@ -73,8 +73,6 @@ class ResourceTest < Test::Unit::TestCase
73
73
  assert_equal @inst.print_variable(:a), ":a"
74
74
  assert_equal @inst.print_variable({:a => "a"}), ":a => \"a\""
75
75
  assert_equal @inst.print_variable(644), "644"
76
- assert_equal @inst.print_variable("0755"), "0755"
77
- assert_equal @inst.print_variable("755"), "0755"
78
76
  assert_equal @inst.print_variable(@inst), @inst.to_s
79
77
  assert_equal @inst.print_variable(nil), nil
80
78
  end
@@ -147,4 +145,18 @@ class ResourceTest < Test::Unit::TestCase
147
145
  end
148
146
  end
149
147
 
148
+ def test_a_subclassed_resource_has_the_method_of_the_subclassed_resource
149
+ pool "oblong" do
150
+ cloud "piece" do
151
+ fake_plugin do
152
+ has_subclassed "box"
153
+ end
154
+ end
155
+ end
156
+
157
+ assert_equal PoolParty::Resources::FakePlugin, clouds["piece"].resources.first.class
158
+ assert_equal PoolParty::Resources::FakeSubclassedPlugin, clouds["piece"].resources.first.resources[0].class
159
+ assert_equal 1, clouds["piece"].resources.first.resources[0].resources.size
160
+ end
161
+
150
162
  end
@@ -12,7 +12,7 @@ class DirectoryResourceTest < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  should "have the directory method denoted by has_method_name" do
15
- str = "directory \"/etc/poolparty\" do\n action :create\n recursive true\n mode 0644\n owner \"root\"\n group \"root\"\nend\n"
15
+ str = "directory \"/etc/poolparty\" do\n action :create\n recursive true\n mode \"0644\"\n owner \"root\"\n group \"root\"\nend\n"
16
16
  assert_equal str, @base.compile(@res)
17
17
  end
18
18
 
@@ -13,7 +13,7 @@ class DirectoryResourceTest < Test::Unit::TestCase
13
13
  end
14
14
 
15
15
  should "have the template method denoted by has_method_name" do
16
- str = "template \"/etc/poolparty/lyrics\" do\n source \"/etc/poolparty/lyrics.erb\"\n action :create\n backup 5\n mode 0644\n owner \"root\"\nend\n"
16
+ str = "template \"/etc/poolparty/lyrics\" do\n source \"/etc/poolparty/lyrics.erb\"\n action :create\n backup 5\n mode \"0644\"\n owner \"root\"\nend\n"
17
17
 
18
18
  assert_equal str, @base.compile(@res)
19
19
  assert_equal "I'm just a file, a lonely little file in the world", open(@cookboox_directory/"templates"/"default"/"etc"/"poolparty"/"lyrics.erb").read
@@ -16,7 +16,7 @@ str = <<-EOS
16
16
  user "random" do
17
17
  action :create
18
18
  comment "Random User"
19
- uid 1000
19
+ uid \"1000\"
20
20
  gid "users"
21
21
  home "/home/random"
22
22
  shell "/bin/zsh"
@@ -16,29 +16,4 @@ class BootstrapperTest < Test::Unit::TestCase
16
16
  end
17
17
  end
18
18
 
19
- context "configure_script" do
20
- setup do
21
- clear!
22
- @filepath = fixtures_dir/"clouds/simple_cloud.rb"
23
- @pool = PoolParty::Pool.load_from_file(@filepath)
24
- @cloud = @pool.clouds[@pool.clouds.keys.first]
25
- @outfile = test_dir/"configure_script.sh"
26
- end
27
-
28
- should "get the script for ubuntu" do
29
- assert_equal File.expand_path(@outfile), Provision::Bootstrapper.configure_script(@cloud, :ubuntu, @outfile)
30
- end
31
-
32
- should "output some stuffies" do
33
- assert_match /echo app > \/etc\/poolparty\/cloud_name/, open(@outfile).read
34
- assert_match /echo poolparty > \/etc\/poolparty\/pool_name/, open(@outfile).read
35
- end
36
-
37
- should "raise an exception if the os isn't supported yet" do
38
- assert_raises StandardError do
39
- Provision::Bootstrapper.configure_script(@cloud, :non_existant_os)
40
- end
41
- end
42
- end
43
-
44
19
  end
data/test/test_helper.rb CHANGED
@@ -27,4 +27,3 @@ require "shoulda"
27
27
  require 'git-style-binary/command'
28
28
 
29
29
  GitStyleBinary.run = true
30
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auser-poolparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.13
4
+ version: 1.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Lerner
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-09-04 00:00:00 -07:00
14
+ date: 2009-09-18 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies: []
17
17
 
@@ -276,6 +276,7 @@ files:
276
276
  - test/fixtures/keys/test_pub_key
277
277
  - test/fixtures/resources/fake_plugin.rb
278
278
  - test/fixtures/resources/fake_resource.rb
279
+ - test/fixtures/resources/fake_subclassed_plugin.rb
279
280
  - test/fixtures/resources/random_proc_file.rb
280
281
  - test/fixtures/templates/apache_conf.erb
281
282
  - test/fixtures/test_template.erb
@@ -1114,6 +1115,7 @@ files:
1114
1115
  - vendor/gems/trollop/www/index.html
1115
1116
  has_rdoc: false
1116
1117
  homepage: http://poolpartyrb.com
1118
+ licenses:
1117
1119
  post_install_message:
1118
1120
  rdoc_options:
1119
1121
  - --quiet
@@ -1139,7 +1141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1139
1141
  requirements: []
1140
1142
 
1141
1143
  rubyforge_project:
1142
- rubygems_version: 1.2.0
1144
+ rubygems_version: 1.3.5
1143
1145
  signing_key:
1144
1146
  specification_version: 3
1145
1147
  summary: Self-healing, auto-scaling system administration, provisioning and maintaining tool that makes cloud computing easier.