auser-poolparty 1.3.13 → 1.3.14

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 (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.