auser-poolparty 1.3.5 → 1.3.6

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 (47) hide show
  1. data/Rakefile +2 -2
  2. data/VERSION.yml +1 -1
  3. data/bin/cloud-misc +34 -0
  4. data/bin/{poolparty-setup → cloud-setup} +0 -0
  5. data/bin/cloud-ssh +4 -1
  6. data/config/jeweler.rb +4 -3
  7. data/examples/monitored_cloud.rb +1 -1
  8. data/examples/thrift/thrift_example.rb +5 -3
  9. data/examples/vmware.rb +10 -0
  10. data/lib/cloud_providers/cloud_provider_instance.rb +13 -4
  11. data/lib/cloud_providers/connections.rb +1 -1
  12. data/lib/core/file.rb +12 -0
  13. data/lib/dependency_resolvers/base.rb +1 -1
  14. data/lib/dependency_resolvers/chef.rb +7 -5
  15. data/lib/dependency_resolvers/proxy_object.rb +11 -3
  16. data/lib/poolparty.rb +3 -1
  17. data/lib/poolparty/base.rb +1 -2
  18. data/lib/poolparty/cloud.rb +20 -5
  19. data/lib/poolparty/default.rb +1 -0
  20. data/lib/poolparty/plugin.rb +1 -5
  21. data/lib/poolparty/plugins/apache.rb +8 -6
  22. data/lib/poolparty/plugins/collectd.rb +24 -0
  23. data/lib/poolparty/plugins/collectd/templates/collectd.conf.erb +369 -0
  24. data/lib/poolparty/plugins/hermes.rb +89 -0
  25. data/lib/poolparty/pool.rb +26 -3
  26. data/lib/poolparty/resource.rb +12 -11
  27. data/lib/poolparty/resources/line.rb +2 -2
  28. data/lib/poolparty/resources/variable.rb +4 -3
  29. data/lib/proto/command_interface_handler.rb +17 -1
  30. data/lib/proto/gen-py/cloudthrift/CommandInterface.pyc +0 -0
  31. data/lib/proto/gen-py/cloudthrift/__init__.pyc +0 -0
  32. data/lib/proto/gen-py/cloudthrift/constants.pyc +0 -0
  33. data/lib/proto/gen-py/cloudthrift/ttypes.pyc +0 -0
  34. data/lib/proto/gen-py/thrift/Thrift.pyc +0 -0
  35. data/lib/proto/gen-py/thrift/__init__.pyc +0 -0
  36. data/lib/proto/gen-py/thrift/protocol/TBinaryProtocol.pyc +0 -0
  37. data/lib/proto/gen-py/thrift/protocol/TProtocol.pyc +0 -0
  38. data/lib/proto/gen-py/thrift/protocol/__init__.pyc +0 -0
  39. data/lib/proto/gen-py/thrift/transport/TSocket.pyc +0 -0
  40. data/lib/proto/gen-py/thrift/transport/TTransport.pyc +0 -0
  41. data/lib/proto/gen-py/thrift/transport/__init__.pyc +0 -0
  42. data/test/lib/dependency_resolvers/chef_test.rb +92 -100
  43. data/test/lib/poolparty/cloud_test.rb +50 -2
  44. data/test/lib/poolparty/monitor_test.rb +2 -2
  45. data/test/lib/poolparty/resource_test.rb +5 -0
  46. data/test/lib/poolparty/resources/variable_test.rb +33 -10
  47. metadata +11 -4
data/Rakefile CHANGED
@@ -39,8 +39,8 @@ end
39
39
 
40
40
  # Generate documentation
41
41
  Rake::RDocTask.new do |rd|
42
- rd.main = "Readme.txt"
43
- rd.rdoc_files.include("Readme.txt", "lib/**/*.rb")
42
+ rd.main = "README.rdoc"
43
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
44
44
  rd.rdoc_dir = "rdoc"
45
45
  # rd.template = "hanaa"
46
46
  end
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 3
3
- :patch: 5
3
+ :patch: 6
4
4
  :major: 1
data/bin/cloud-misc ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(__FILE__) + "/../lib")
3
+ require "poolparty"
4
+
5
+ require 'git-style-binary/command'
6
+
7
+ GitStyleBinary.command do
8
+ banner <<-EOS
9
+ Usage: #{$0} #{all_options_string}
10
+
11
+ read the code
12
+ EOS
13
+
14
+ short_desc "various cloud development tasks"
15
+
16
+ opt :inst_num, "The number of the instance to run bootstrap on", :type => :int
17
+ opt :force, "Force rebootstrapping (useful for upgrading)", :default => false
18
+
19
+ run do |command|
20
+ @loaded_clouds.each do |cld|
21
+ cld.nodes.each do |node|
22
+
23
+ case command.argv.shift
24
+ when "deploy_hermes"
25
+ hermesdir = File.dirname(__FILE__) + "/../vendor/erlang/hermes"
26
+ release = `#{hermesdir}/scripts/most_recent_release tar.gz`.strip
27
+ node.scp(:source => release, :destination => "/var/poolparty/tmp")
28
+ node.scp(:source => "#{hermesdir}/scripts/target_system", :destination => "/var/poolparty/tmp")
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
File without changes
data/bin/cloud-ssh CHANGED
@@ -13,11 +13,14 @@ EOS
13
13
 
14
14
  short_desc "ssh into an instance of the cloud"
15
15
 
16
+ opt :instance_number, "Ssh into the instance number", :type => :integer, :default => 0
17
+
16
18
  run do |command|
17
19
  cloud = @loaded_clouds.first
18
20
 
19
21
  if !cloud.nodes.empty?
20
- cloud.nodes.first.ssh
22
+ inst = cloud.nodes[command[:instance_number]]
23
+ inst ? inst.ssh : puts("Error: The instance number (#{command[:instance_number]}) is too high for the current number of instances")
21
24
  else
22
25
  puts "No running instances can be found"
23
26
  end
data/config/jeweler.rb CHANGED
@@ -26,11 +26,12 @@ end
26
26
 
27
27
  s.files = (%w(Rakefile README.rdoc License.txt VERSION.yml) + Dir["{config,examples,lib,test,tasks,script,generators,bin,vendor}/**/*"])
28
28
 
29
- s.files.exclude '**/*.beam'
30
- s.files.exclude "**/*/erl_crash.dump"
29
+ s.files.exclude 'vendor/erlang/*'
30
+ s.files.exclude 'examples/thrift/**/*.beam'
31
+ # s.files.exclude "**/*/erl_crash.dump"
31
32
 
32
33
  s.has_rdoc = true
33
- s.extra_rdoc_files = ["README.txt", "License.txt", 'History.txt']
34
+ s.extra_rdoc_files = ["README.rdoc", "License.txt", 'History.txt']
34
35
  s.require_paths = ["lib"]
35
36
  s.rdoc_options = ['--quiet', '--title', 'PoolParty documentation',
36
37
  # "index.html",
@@ -10,7 +10,7 @@ pool "poolparty" do
10
10
  image_id 'emi-39CA160F'
11
11
  end
12
12
 
13
- monitor :cpu do |c|
13
+ monitor :'cpu-idle' do |c|
14
14
  vote_for(:expand) if c > 0.9
15
15
  vote_for(:contract) if c < 0.1
16
16
  end
@@ -3,7 +3,7 @@
3
3
  $:.unshift(File.dirname(__FILE__) + "/../../lib")
4
4
  $:.unshift(File.dirname(__FILE__) + "/../../examples")
5
5
  require "poolparty"
6
- require "simple"
6
+ # require "simple"
7
7
 
8
8
  $:.unshift("#{File.dirname(__FILE__)}/../../lib/proto/gen-rb")
9
9
 
@@ -15,6 +15,7 @@ require "poolparty_types"
15
15
  port = ARGV.pop || 11223
16
16
 
17
17
  transport = Thrift::BufferedTransport.new(Thrift::Socket.new('localhost', port))
18
+ # transport = Thrift::BufferedTransport.new(Thrift::Socket.new('vm', port))
18
19
  protocol = Thrift::BinaryProtocol.new(transport)
19
20
 
20
21
  client = CloudThrift::CommandInterface::Client.new(protocol)
@@ -22,6 +23,7 @@ transport.open()
22
23
 
23
24
  cld = CloudThrift::CloudQuery.new
24
25
  cld.name = 'monitored_app'
26
+ # cld.name = 'vmware'
25
27
 
26
28
  resp = client.run_command(cld, "name", [])
27
29
  puts resp.response
@@ -29,8 +31,8 @@ puts resp.response
29
31
  resp = client.run_command(cld, "maximum_instances", [])
30
32
  puts resp.response
31
33
 
32
- resp = client.run_command(cld, "run_monitor", ["cpu", "0.91"])
34
+ resp = client.run_command(cld, "run_monitor", ["cpu-idle", "0.91"])
33
35
  p resp.response
34
36
 
35
- resp = client.run_command(cld, "run_monitor", ["cpu", "0.01"])
37
+ resp = client.run_command(cld, "run_monitor", ["cpu-idle", "0.01"])
36
38
  p resp.response
data/examples/vmware.rb CHANGED
@@ -10,9 +10,19 @@ pool "poolparty" do
10
10
  image_id "/Users/nmurray/Documents/VMware/Ubuntu-jaunty.vmwarevm/Ubuntu-jaunty.vmx"
11
11
  public_ip "192.168.133.128"
12
12
  end
13
+ has_hermes
13
14
  has_file "/etc/motd", :content => "welcome to your instance"
14
15
 
15
16
  has_convenience_helpers
16
17
  end
17
18
 
18
19
  end
20
+
21
+ # hermes
22
+ # want to be able to run cloud configure to update it
23
+ # but want to be able to pull from locally to configure it
24
+ # submodules?
25
+ # node name
26
+ # install path
27
+ # how to upload the escript target system
28
+ # how to upload the tar.gz of the release
@@ -66,16 +66,16 @@ module CloudProviders
66
66
  bootstrap! unless bootstrapped?
67
67
  callback :before_configure
68
68
  raise StandardError.new("You must pass in a cloud to configure an instance") unless cloud
69
- cloud.compile(self)
69
+ cloud.compile(self)
70
+
70
71
  scp(:source => keypair.full_filepath,
71
72
  :destination => "/etc/poolparty/keys/#{keypair.basename}")
72
- script_file = Provision::Bootstrapper.configure_script(cloud, os)
73
73
 
74
74
  FileUtils.mkdir_p cloud.tmp_path/"etc"/"poolparty" unless File.directory?(cloud.tmp_path/"etc"/"poolparty")
75
- FileUtils.cp script_file, cloud.tmp_path/"etc"/"poolparty"
75
+ pack_clouds_dot_rb_and_expected_directories
76
76
 
77
+ dputs("Rsyncing #{cloud.tmp_path/"*"}")
77
78
  rsync(:source => cloud.tmp_path/"*", :destination => "/")
78
- run("chmod +x /etc/poolparty/#{File.basename(script_file)}; /bin/sh /etc/poolparty/#{File.basename(script_file)}").chomp
79
79
  run(cloud.dependency_resolver.compile_command)
80
80
  callback :after_configure
81
81
  end
@@ -95,6 +95,15 @@ module CloudProviders
95
95
  end
96
96
  alias :platform :os # Chef uses platform, aliased for conveneince
97
97
 
98
+ def pack_clouds_dot_rb_and_expected_directories
99
+ %w(lib plugins).each do |dir|
100
+ if File.directory?(d = cloud.clouds_dot_rb_dir/dir)
101
+ dputs("Adding local path: #{d}")
102
+ FileUtils.cp_r d, cloud.tmp_path/cloud.base_config_directory, :verbose => true, :remove_destination => true # req'd for symlinks
103
+ end
104
+ end
105
+ FileUtils.cp cloud.clouds_dot_rb_file, cloud.tmp_path/"/etc/poolparty/clouds.rb"
106
+ end
98
107
  # Determine the os
99
108
  # Default to ubuntu
100
109
  # Send the determine_os.sh script to the node and run it remotely
@@ -51,7 +51,7 @@ module CloudProviders
51
51
  raise StandardError.new("You must pass a :source=>uri option to rsync") unless opts[:source]
52
52
  destination_path = opts[:destination] || opts[:source]
53
53
  rsync_opts = opts[:rsync_opts] || '-va'
54
- cmd_string = "rsync -e 'ssh #{ssh_options}' #{rsync_opts} #{opts[:source]} #{user}@#{host}:#{destination_path}"
54
+ cmd_string = "rsync -L -e 'ssh #{ssh_options}' #{rsync_opts} #{opts[:source]} #{user}@#{host}:#{destination_path}"
55
55
  out = system_run(cmd_string)
56
56
  out
57
57
  end
data/lib/core/file.rb ADDED
@@ -0,0 +1,12 @@
1
+ class File
2
+ class << self
3
+ alias_method :old_symlink, :symlink
4
+ def symlink(old_name, new_name)
5
+ begin
6
+ old_symlink(old_name, new_name)
7
+ rescue Errno::EEXIST
8
+ $stderr.puts "warning: symlinking #{old_name} -> #{new_name}. Already exists"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -111,7 +111,7 @@ module DependencyResolvers
111
111
  when Symbol
112
112
  ":#{obj}"
113
113
  when Hash
114
- "#{obj.map {|k,v| ":#{k} => #{handle_print_variable(v)}" unless v == obj }.compact.join(",\n")}"
114
+ "{#{obj.map {|k,v| ":#{k} => #{handle_print_variable(v)}" unless v == obj }.compact.join(",")}}"
115
115
  else
116
116
  "#{obj}"
117
117
  end
@@ -159,13 +159,15 @@ module DependencyResolvers
159
159
  file_pointers.each do |n,f|
160
160
  f << "\n#{n} Mash.new unless attribute?(\"#{n}\")\n"
161
161
  end
162
- variables.each do |var|
163
-
164
- var_val = handle_print_variable(ProxyObject.new(var, @caller).compile(:value))
162
+ variables.each do |var|
165
163
  if var.parent && !var.parent.is_a?(PoolParty::Cloud)
166
- file_pointers[var.parent.has_method_name] << "#{var.parent.has_method_name}[:#{var.name}] = #{var_val}\n"
164
+ file_pointers[var.parent.has_method_name] << "#{var.parent.has_method_name}[:#{var.name}] ="
165
+ file_pointers[var.parent.has_method_name] << ProxyObject.new(var, @caller).compile(:value)
166
+ file_pointers[var.parent.has_method_name] << "\n"
167
167
  else
168
- file_pointers[:poolparty] << "poolparty[:#{var.name}] = #{var_val}\n"
168
+ file_pointers[:poolparty] << "poolparty[:#{var.name}] = "
169
+ file_pointers[:poolparty] << ProxyObject.new(var, @caller).compile(:value)
170
+ file_pointers[:poolparty] << "\n"
169
171
  end
170
172
  end
171
173
  # Close the files
@@ -32,15 +32,18 @@ module DependencyResolvers
32
32
  meth_name
33
33
  when Symbol
34
34
  @current_printing_method = meth_name
35
- self.send(meth_name).to_s
35
+ self.send(meth_name)
36
36
  else
37
37
  raise PoolParty::PoolPartyError.create("ProxyObjectError", "Compilation of #{proxy.inspect} error. Strings and symbols are supported")
38
38
  end
39
+
40
+ str = handle_print_variable(str) if proxy.class == PoolParty::Resources::Variable
41
+
39
42
  begin
40
43
  ERB.new(str).result(self.send(:binding))
41
44
  rescue Exception => e
42
- p [:error, e, str]
43
- end
45
+ ""
46
+ end
44
47
  end
45
48
 
46
49
  # Print the dsl options in the Erb string format
@@ -73,6 +76,11 @@ module DependencyResolvers
73
76
  end.join("\n")
74
77
  end
75
78
 
79
+ # Print variables
80
+ def handle_print_variable(var)
81
+ DependencyResolvers::Base.handle_print_variable(var)
82
+ end
83
+
76
84
  def instance
77
85
  @caller
78
86
  end
data/lib/poolparty.rb CHANGED
@@ -43,7 +43,9 @@ require "poolparty/pool_party_error"
43
43
  hash
44
44
  symbol
45
45
  proc
46
- time).each do |lib|
46
+ time
47
+ file
48
+ ).each do |lib|
47
49
  require "core/#{lib}"
48
50
  end
49
51
 
@@ -37,8 +37,7 @@ module PoolParty
37
37
  # - stack
38
38
  def run_in_context(o={}, &block)
39
39
  proc = Proc.new do
40
- # Name MUST be set first
41
- set_vars_from_options(:name => o[:name]) if o.has_key?(:name)
40
+ set_vars_from_options(:name => o[:name]) if o.has_key?(:name) # Name MUST be set first
42
41
  set_vars_from_options(o)
43
42
  instance_eval &block if block
44
43
  end
@@ -27,6 +27,8 @@ module PoolParty
27
27
  end
28
28
 
29
29
  def before_compile
30
+ add_monitoring_stack_if_needed
31
+
30
32
  validate_all_resources
31
33
  end
32
34
 
@@ -61,7 +63,7 @@ module PoolParty
61
63
  end
62
64
 
63
65
  # Cloud provider methods
64
- def nodes(o={}); delayed_action {cloud_provider.nodes(o)}; end
66
+ def nodes(o={}); delayed_action {cloud_provider.nodes(o).collect{|n| n.cloud = self; n}}; end
65
67
  def run_instance(o={}); cloud_provider.run_instance(o);end
66
68
  def terminate_instance!(o={}); cloud_provider.terminate_instance!(o);end
67
69
  def describe_instances(o={}); cloud_provider.describe_instances(o);end
@@ -87,7 +89,7 @@ module PoolParty
87
89
 
88
90
  # 1.) Launches a new instance,
89
91
  # 2.) Waits for the instance to get an ip address
90
- # 3.) Waits for port 22 to be open
92
+ # 3.) Waits for port ssh_port to be open
91
93
  # 4.) Calls call_after_launch_instance callbacks
92
94
  # 5.) Executes passed &block, if any
93
95
  # 6.) Returns the new instance object
@@ -98,7 +100,7 @@ module PoolParty
98
100
  instance.cloud = self
99
101
  @instance = instance
100
102
  #wait for an ip and then wait for ssh port, then configure instance
101
- if instance.wait_for_public_ip(timeout) && instance.wait_for_port(22, :timeout=>timeout)
103
+ if instance.wait_for_public_ip(timeout) && instance.wait_for_port(ssh_port, :timeout=>timeout)
102
104
  callback :after_launch_instance
103
105
  instance.callback :before_bootstrap
104
106
  instance.bootstrap!
@@ -109,7 +111,7 @@ module PoolParty
109
111
  block.call(instance) if block
110
112
  instance
111
113
  else
112
- raise StandardError.new("Instance port 22 not available")
114
+ raise StandardError.new("Instance port #{ssh_port} not available")
113
115
  end
114
116
  instance.refresh!
115
117
  instance
@@ -126,7 +128,7 @@ module PoolParty
126
128
 
127
129
  # convenience method to loop thru all the nodes and configure them
128
130
  def configure!(opts={}, threaded=true)
129
- nodes.collect{|n| n.configure!}
131
+ nodes.collect{|n| n.configure! }
130
132
  end
131
133
 
132
134
  # Run command/s on all nodes in the cloud.
@@ -177,6 +179,19 @@ module PoolParty
177
179
  end
178
180
  end
179
181
 
182
+ # Add the monitoring stack
183
+ def add_monitoring_stack_if_needed
184
+ if monitors.size > 0
185
+
186
+ run_in_context do
187
+ %w(collectd hermes).each do |m|
188
+ self.send m.to_sym
189
+ end
190
+ end
191
+
192
+ end
193
+ end
194
+
180
195
  # Take the cloud's resources and compile them down using
181
196
  # the defined (or the default dependency_resolver, chef)
182
197
  def compile(caller=nil)
@@ -11,6 +11,7 @@ module PoolParty
11
11
  default_options(
12
12
  :user => "root",
13
13
  :os => :ubuntu,
14
+ :ssh_port => 22,
14
15
  :tmp_path => "/tmp/poolparty",
15
16
  :poolparty_home_path => "#{ENV["HOME"]}/.poolparty",
16
17
  :ec2_home => "#{ENV["HOME"]}/.ec2",
@@ -2,11 +2,7 @@
2
2
  Simply a stub class for documentation purposes
3
3
  Plugins are all resources
4
4
  =end
5
- module PoolParty
6
- class Plugin
7
- end
8
- end
9
5
 
10
- %w(apache git rails).each do |plugin|
6
+ %w(apache git rails collectd hermes).each do |plugin|
11
7
  require "plugins/#{plugin}"
12
8
  end
@@ -50,7 +50,7 @@ module PoolParty
50
50
  passenger_configs
51
51
 
52
52
  has_exec "install_passenger_script" do
53
- command "passenger-install-apache2-module -auto"
53
+ command "passenger-install-apache2-module --auto"
54
54
  notifies get_exec("restart-apache2"), :run
55
55
  requires get_exec("restart-apache2")
56
56
  requires get_package("apache2")
@@ -157,14 +157,16 @@ PassengerRuby <%= @node[:languages][:ruby][:ruby_bin] %>
157
157
  end
158
158
 
159
159
  def install_site(name, opts={})
160
- opts.merge!(:name => "/etc/apache2/sites-available/#{name}")
160
+ sitename = name
161
+
162
+ opts.merge!(:name => "/etc/apache2/sites-available/#{sitename}")
161
163
  has_directory(:name => "/etc/apache2/sites-available")
162
164
  has_file(opts) unless opts[:no_file]
163
- has_exec(:name => "/usr/sbin/a2ensite #{name}") do
165
+ has_exec(:name => "/usr/sbin/a2ensite #{sitename}") do
164
166
  notifies get_exec("reload-apache2"), :run
165
167
  requires get_exec("reload-apache2")
166
- requires get_file("/etc/apache2/sites-available/#{name}")
167
- not_if "/bin/sh -c '[ -L /etc/apache2/sites-enabled/#{name} ] && [ /etc/apache2/sites-enabled/#{name} -ef /etc/apache2/sites-available/#{name} ]'"
168
+ requires get_file("/etc/apache2/sites-available/#{sitename}")
169
+ not_if "/bin/sh -c '[ -L /etc/apache2/sites-enabled/#{sitename} ] && [ /etc/apache2/sites-enabled/#{sitename} -ef /etc/apache2/sites-available/#{sitename} ]'"
168
170
  end
169
171
  end
170
172
 
@@ -202,4 +204,4 @@ end
202
204
  $:.unshift(File.dirname(__FILE__))
203
205
  %w(php5 virtual_host passenger_site).each do |lib|
204
206
  require "apache2/#{lib}"
205
- end
207
+ end
@@ -0,0 +1,24 @@
1
+ module PoolParty
2
+ module Resources
3
+
4
+ class Collectd < Resource
5
+
6
+ PoolParty::Resources::FileResource.has_searchable_paths(:prepend_paths=> [File.dirname(__FILE__)+'/collectd/templates'])
7
+
8
+ def after_loaded
9
+ has_package 'collectd'
10
+ %w(rrdtool librrd-dev librrd-ruby libsensors-dev libsnmp-dev collectd collectd-dev).each{|pkg|
11
+ has_package pkg
12
+ }
13
+ has_gem_package "astro-collectd"
14
+
15
+ has_variable 'server', "localhost"
16
+ has_file '/etc/collectd/collectd.conf' do
17
+ template 'collectd.conf.erb'
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end