poolparty 1.3.4 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/Rakefile +2 -2
  2. data/VERSION.yml +1 -1
  3. data/bin/cloud-bootstrap +1 -0
  4. data/bin/cloud-configure +1 -0
  5. data/bin/cloud-contract +1 -0
  6. data/bin/cloud-misc +34 -0
  7. data/bin/cloud-setup +36 -0
  8. data/bin/cloud-ssh +4 -1
  9. data/config/jeweler.rb +4 -3
  10. data/examples/monitored_cloud.rb +1 -1
  11. data/examples/thrift/thrift_example.rb +5 -3
  12. data/examples/vmware.rb +28 -0
  13. data/lib/cloud_providers/cloud_provider_instance.rb +14 -5
  14. data/lib/cloud_providers/connections.rb +1 -1
  15. data/lib/core/file.rb +12 -0
  16. data/lib/core/object.rb +2 -2
  17. data/lib/dependency_resolvers/base.rb +1 -1
  18. data/lib/dependency_resolvers/chef.rb +9 -7
  19. data/lib/dependency_resolvers/proxy_object.rb +11 -3
  20. data/lib/mixins/askable.rb +16 -7
  21. data/lib/poolparty/base.rb +8 -7
  22. data/lib/poolparty/cloud.rb +77 -7
  23. data/lib/poolparty/default.rb +1 -0
  24. data/lib/poolparty/installer.rb +8 -4
  25. data/lib/poolparty/installers/ec2.rb +75 -5
  26. data/lib/poolparty/installers/vmware.rb +17 -5
  27. data/lib/poolparty/plugin.rb +1 -5
  28. data/lib/poolparty/plugins/apache.rb +10 -7
  29. data/lib/poolparty/plugins/apache2/base.conf.erb +2 -2
  30. data/lib/poolparty/plugins/apache2/browser_fixes.conf.erb +1 -1
  31. data/lib/poolparty/plugins/apache2/passenger_site.rb +2 -2
  32. data/lib/poolparty/plugins/collectd/templates/collectd.conf.erb +369 -0
  33. data/lib/poolparty/plugins/collectd.rb +24 -0
  34. data/lib/poolparty/plugins/hermes.rb +89 -0
  35. data/lib/poolparty/pool.rb +33 -3
  36. data/lib/poolparty/resource.rb +32 -18
  37. data/lib/poolparty/resources/directory.rb +5 -1
  38. data/lib/poolparty/resources/exec.rb +2 -2
  39. data/lib/poolparty/resources/file.rb +8 -2
  40. data/lib/poolparty/resources/gem_package.rb +2 -2
  41. data/lib/poolparty/resources/line.rb +23 -6
  42. data/lib/poolparty/resources/mount.rb +2 -2
  43. data/lib/poolparty/resources/package.rb +2 -2
  44. data/lib/poolparty/resources/service.rb +2 -2
  45. data/lib/poolparty/resources/user.rb +2 -2
  46. data/lib/poolparty/resources/variable.rb +4 -3
  47. data/lib/poolparty.rb +5 -3
  48. data/lib/proto/command_interface_handler.rb +17 -1
  49. data/lib/proto/gen-py/cloudthrift/CommandInterface.pyc +0 -0
  50. data/lib/proto/gen-py/cloudthrift/__init__.pyc +0 -0
  51. data/lib/proto/gen-py/cloudthrift/constants.pyc +0 -0
  52. data/lib/proto/gen-py/cloudthrift/ttypes.pyc +0 -0
  53. data/lib/proto/gen-py/thrift/Thrift.pyc +0 -0
  54. data/lib/proto/gen-py/thrift/__init__.pyc +0 -0
  55. data/lib/proto/gen-py/thrift/protocol/TBinaryProtocol.pyc +0 -0
  56. data/lib/proto/gen-py/thrift/protocol/TProtocol.pyc +0 -0
  57. data/lib/proto/gen-py/thrift/protocol/__init__.pyc +0 -0
  58. data/lib/proto/gen-py/thrift/transport/TSocket.pyc +0 -0
  59. data/lib/proto/gen-py/thrift/transport/TTransport.pyc +0 -0
  60. data/lib/proto/gen-py/thrift/transport/__init__.pyc +0 -0
  61. data/test/lib/dependency_resolvers/chef_test.rb +92 -100
  62. data/test/lib/poolparty/base_test.rb +13 -0
  63. data/test/lib/poolparty/cloud_test.rb +50 -2
  64. data/test/lib/poolparty/monitor_test.rb +2 -2
  65. data/test/lib/poolparty/resource_test.rb +5 -0
  66. data/test/lib/poolparty/resources/line_test.rb +3 -3
  67. data/test/lib/poolparty/resources/service_test.rb +1 -1
  68. data/test/lib/poolparty/resources/variable_test.rb +33 -10
  69. data/vendor/gems/net-ssh/CHANGELOG.rdoc +127 -0
  70. data/vendor/gems/net-ssh/Manifest +104 -0
  71. data/vendor/gems/net-ssh/README.rdoc +110 -0
  72. data/vendor/gems/net-ssh/Rakefile +26 -0
  73. data/vendor/gems/net-ssh/THANKS.rdoc +16 -0
  74. data/vendor/gems/net-ssh/lib/net/ssh/authentication/agent.rb +176 -0
  75. data/vendor/gems/net-ssh/lib/net/ssh/authentication/constants.rb +18 -0
  76. data/vendor/gems/net-ssh/lib/net/ssh/authentication/key_manager.rb +193 -0
  77. data/vendor/gems/net-ssh/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  78. data/vendor/gems/net-ssh/lib/net/ssh/authentication/methods/hostbased.rb +71 -0
  79. data/vendor/gems/net-ssh/lib/net/ssh/authentication/methods/keyboard_interactive.rb +66 -0
  80. data/vendor/gems/net-ssh/lib/net/ssh/authentication/methods/password.rb +39 -0
  81. data/vendor/gems/net-ssh/lib/net/ssh/authentication/methods/publickey.rb +92 -0
  82. data/vendor/gems/net-ssh/lib/net/ssh/authentication/pageant.rb +183 -0
  83. data/vendor/gems/net-ssh/lib/net/ssh/authentication/session.rb +134 -0
  84. data/vendor/gems/net-ssh/lib/net/ssh/buffer.rb +340 -0
  85. data/vendor/gems/net-ssh/lib/net/ssh/buffered_io.rb +149 -0
  86. data/vendor/gems/net-ssh/lib/net/ssh/config.rb +181 -0
  87. data/vendor/gems/net-ssh/lib/net/ssh/connection/channel.rb +625 -0
  88. data/vendor/gems/net-ssh/lib/net/ssh/connection/constants.rb +33 -0
  89. data/vendor/gems/net-ssh/lib/net/ssh/connection/session.rb +596 -0
  90. data/vendor/gems/net-ssh/lib/net/ssh/connection/term.rb +178 -0
  91. data/vendor/gems/net-ssh/lib/net/ssh/errors.rb +85 -0
  92. data/vendor/gems/net-ssh/lib/net/ssh/key_factory.rb +102 -0
  93. data/vendor/gems/net-ssh/lib/net/ssh/known_hosts.rb +129 -0
  94. data/vendor/gems/net-ssh/lib/net/ssh/loggable.rb +61 -0
  95. data/vendor/gems/net-ssh/lib/net/ssh/packet.rb +102 -0
  96. data/vendor/gems/net-ssh/lib/net/ssh/prompt.rb +93 -0
  97. data/vendor/gems/net-ssh/lib/net/ssh/proxy/errors.rb +14 -0
  98. data/vendor/gems/net-ssh/lib/net/ssh/proxy/http.rb +94 -0
  99. data/vendor/gems/net-ssh/lib/net/ssh/proxy/socks4.rb +70 -0
  100. data/vendor/gems/net-ssh/lib/net/ssh/proxy/socks5.rb +129 -0
  101. data/vendor/gems/net-ssh/lib/net/ssh/ruby_compat.rb +7 -0
  102. data/vendor/gems/net-ssh/lib/net/ssh/service/forward.rb +267 -0
  103. data/vendor/gems/net-ssh/lib/net/ssh/test/channel.rb +129 -0
  104. data/vendor/gems/net-ssh/lib/net/ssh/test/extensions.rb +152 -0
  105. data/vendor/gems/net-ssh/lib/net/ssh/test/kex.rb +44 -0
  106. data/vendor/gems/net-ssh/lib/net/ssh/test/local_packet.rb +51 -0
  107. data/vendor/gems/net-ssh/lib/net/ssh/test/packet.rb +81 -0
  108. data/vendor/gems/net-ssh/lib/net/ssh/test/remote_packet.rb +38 -0
  109. data/vendor/gems/net-ssh/lib/net/ssh/test/script.rb +157 -0
  110. data/vendor/gems/net-ssh/lib/net/ssh/test/socket.rb +59 -0
  111. data/vendor/gems/net-ssh/lib/net/ssh/test.rb +89 -0
  112. data/vendor/gems/net-ssh/lib/net/ssh/transport/algorithms.rb +384 -0
  113. data/vendor/gems/net-ssh/lib/net/ssh/transport/cipher_factory.rb +80 -0
  114. data/vendor/gems/net-ssh/lib/net/ssh/transport/constants.rb +30 -0
  115. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/abstract.rb +78 -0
  116. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/md5.rb +12 -0
  117. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  118. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/none.rb +15 -0
  119. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  120. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  121. data/vendor/gems/net-ssh/lib/net/ssh/transport/hmac.rb +31 -0
  122. data/vendor/gems/net-ssh/lib/net/ssh/transport/identity_cipher.rb +55 -0
  123. data/vendor/gems/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  124. data/vendor/gems/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  125. data/vendor/gems/net-ssh/lib/net/ssh/transport/kex.rb +13 -0
  126. data/vendor/gems/net-ssh/lib/net/ssh/transport/openssl.rb +128 -0
  127. data/vendor/gems/net-ssh/lib/net/ssh/transport/packet_stream.rb +230 -0
  128. data/vendor/gems/net-ssh/lib/net/ssh/transport/server_version.rb +60 -0
  129. data/vendor/gems/net-ssh/lib/net/ssh/transport/session.rb +276 -0
  130. data/vendor/gems/net-ssh/lib/net/ssh/transport/state.rb +201 -0
  131. data/vendor/gems/net-ssh/lib/net/ssh/verifiers/lenient.rb +30 -0
  132. data/vendor/gems/net-ssh/lib/net/ssh/verifiers/null.rb +12 -0
  133. data/vendor/gems/net-ssh/lib/net/ssh/verifiers/strict.rb +53 -0
  134. data/vendor/gems/net-ssh/lib/net/ssh/version.rb +62 -0
  135. data/vendor/gems/net-ssh/lib/net/ssh.rb +215 -0
  136. data/vendor/gems/net-ssh/net-ssh.gemspec +33 -0
  137. data/vendor/gems/net-ssh/setup.rb +1585 -0
  138. data/vendor/gems/net-ssh/test/authentication/methods/common.rb +28 -0
  139. data/vendor/gems/net-ssh/test/authentication/methods/test_abstract.rb +51 -0
  140. data/vendor/gems/net-ssh/test/authentication/methods/test_hostbased.rb +114 -0
  141. data/vendor/gems/net-ssh/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  142. data/vendor/gems/net-ssh/test/authentication/methods/test_password.rb +50 -0
  143. data/vendor/gems/net-ssh/test/authentication/methods/test_publickey.rb +127 -0
  144. data/vendor/gems/net-ssh/test/authentication/test_agent.rb +205 -0
  145. data/vendor/gems/net-ssh/test/authentication/test_key_manager.rb +105 -0
  146. data/vendor/gems/net-ssh/test/authentication/test_session.rb +93 -0
  147. data/vendor/gems/net-ssh/test/common.rb +106 -0
  148. data/vendor/gems/net-ssh/test/configs/eqsign +3 -0
  149. data/vendor/gems/net-ssh/test/configs/exact_match +8 -0
  150. data/vendor/gems/net-ssh/test/configs/wild_cards +14 -0
  151. data/vendor/gems/net-ssh/test/connection/test_channel.rb +452 -0
  152. data/vendor/gems/net-ssh/test/connection/test_session.rb +488 -0
  153. data/vendor/gems/net-ssh/test/test_all.rb +6 -0
  154. data/vendor/gems/net-ssh/test/test_buffer.rb +336 -0
  155. data/vendor/gems/net-ssh/test/test_buffered_io.rb +63 -0
  156. data/vendor/gems/net-ssh/test/test_config.rb +84 -0
  157. data/vendor/gems/net-ssh/test/test_key_factory.rb +67 -0
  158. data/vendor/gems/net-ssh/test/transport/hmac/test_md5.rb +39 -0
  159. data/vendor/gems/net-ssh/test/transport/hmac/test_md5_96.rb +25 -0
  160. data/vendor/gems/net-ssh/test/transport/hmac/test_none.rb +34 -0
  161. data/vendor/gems/net-ssh/test/transport/hmac/test_sha1.rb +34 -0
  162. data/vendor/gems/net-ssh/test/transport/hmac/test_sha1_96.rb +25 -0
  163. data/vendor/gems/net-ssh/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  164. data/vendor/gems/net-ssh/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  165. data/vendor/gems/net-ssh/test/transport/test_algorithms.rb +302 -0
  166. data/vendor/gems/net-ssh/test/transport/test_cipher_factory.rb +171 -0
  167. data/vendor/gems/net-ssh/test/transport/test_hmac.rb +34 -0
  168. data/vendor/gems/net-ssh/test/transport/test_identity_cipher.rb +40 -0
  169. data/vendor/gems/net-ssh/test/transport/test_packet_stream.rb +435 -0
  170. data/vendor/gems/net-ssh/test/transport/test_server_version.rb +57 -0
  171. data/vendor/gems/net-ssh/test/transport/test_session.rb +315 -0
  172. data/vendor/gems/net-ssh/test/transport/test_state.rb +173 -0
  173. metadata +116 -4
  174. data/bin/install-poolparty +0 -20
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: 4
3
+ :patch: 6
4
4
  :major: 1
data/bin/cloud-bootstrap CHANGED
@@ -21,6 +21,7 @@ EOS
21
21
  @loaded_clouds.each do |cld|
22
22
 
23
23
  cld.nodes.each do |node|
24
+ node.cloud = cld # needed for bootstrap
24
25
  node.bootstrap!(:force=>command[:force])
25
26
  end
26
27
 
data/bin/cloud-configure CHANGED
@@ -26,6 +26,7 @@ EOS
26
26
  end
27
27
 
28
28
  cld.nodes.each do |node|
29
+ node.cloud = cld # ?
29
30
  node.configure!(:cloud => cld)
30
31
  end
31
32
 
data/bin/cloud-contract CHANGED
@@ -17,6 +17,7 @@ EOS
17
17
  @loaded_clouds.each do |cld|
18
18
 
19
19
  node_to_terminate = cld.nodes.last
20
+ node_to_terminate.cloud = cld
20
21
 
21
22
  msg = [
22
23
  "Contracting cloud #{cld.name} (#{cld.keypair}) by 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
data/bin/cloud-setup ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+ require "poolparty"
4
+ require "poolparty/installer"
5
+
6
+ require 'git-style-binary/command'
7
+
8
+ GitStyleBinary.command do
9
+ banner <<-EOS
10
+ Usage: #{$0} #{all_options_string}
11
+
12
+ Sets up a basic clouds.rb file and carries through the steps to bootstrap a new cloud
13
+ EOS
14
+
15
+ short_desc "Setup a new clouds.rb file"
16
+
17
+ providers = {}
18
+ PoolParty::Installer.all.each_with_index do |installer,idx|
19
+ providers.merge!(idx+1 => installer)
20
+ end
21
+
22
+ str = ["The cloud_provider you'd like to set your clouds.rb for. The available clouds include:"]
23
+ PoolParty::Installer.all.each do |provider|
24
+ str << "\t\t\t\t\t\t\t\t#{provider.name} - #{provider.description}"
25
+ end
26
+ opt :type, str.join("\n"), :type => :string, :default => "ec2"
27
+
28
+ run do |command|
29
+
30
+ klass = PoolParty::Installer.find_by_name(command[:type])
31
+ puts "Great, we'll be using #{klass}"
32
+ inst = klass.send :new
33
+ inst.run
34
+
35
+ end
36
+ end
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
@@ -0,0 +1,28 @@
1
+ require "poolparty"
2
+ require 'poolparty-extensions'
3
+
4
+ pool "poolparty" do
5
+ instances 1
6
+
7
+ cloud "vmware" do
8
+ keypair "id_rsa"
9
+ using :vmware do
10
+ image_id "/Users/nmurray/Documents/VMware/Ubuntu-jaunty.vmwarevm/Ubuntu-jaunty.vmx"
11
+ public_ip "192.168.133.128"
12
+ end
13
+ has_hermes
14
+ has_file "/etc/motd", :content => "welcome to your instance"
15
+
16
+ has_convenience_helpers
17
+ end
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
@@ -222,7 +231,7 @@ module CloudProviders
222
231
  end
223
232
 
224
233
  def on_all_callbacks(call_time, *args, &block)
225
- cloud.callback call_time
234
+ cloud.callback call_time if cloud
226
235
  super
227
236
  end
228
237
 
@@ -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
data/lib/core/object.rb CHANGED
@@ -71,10 +71,10 @@ class Object
71
71
  puts "[INFO] -- #{m}" if verbose?
72
72
  end
73
73
  def dputs(m="")
74
- puts "[DEBUG] -- #{m.inspect}" if debugging?
74
+ puts "[DEBUG] -- #{m.is_a?(String) ? m : m.inspect}" if debugging?
75
75
  end
76
76
  def ddputs(m="")
77
- puts "[VERY DEBUG] -- #{m.inspect}" if very_debugging?
77
+ puts "[VERY DEBUG] -- #{m.is_a?(String) ? m : m.inspect}" if very_debugging?
78
78
  end
79
79
  def verbose?
80
80
  $TESTING ||= false
@@ -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
@@ -26,7 +26,7 @@ module DependencyResolvers
26
26
  end
27
27
 
28
28
  def compile_command
29
- "/usr/bin/chef-solo -c /etc/chef/solo.rb -j /etc/chef/dna.json"
29
+ "/usr/bin/chef-solo -c /etc/chef/solo.rb -j /etc/chef/dna.json#{ " -l debug" if very_debugging?}"
30
30
  end
31
31
 
32
32
  # compile the resources
@@ -57,7 +57,7 @@ module DependencyResolvers
57
57
  super
58
58
  end
59
59
 
60
- apply_meta_functions(res, o) if res.is_a?(PoolParty::Resource)
60
+ apply_meta_functions(res, o) if res.is_a?(PoolParty::Resource) && res.print_to_chef != :no_print
61
61
  end
62
62
 
63
63
  default_attr_reader :variables, []
@@ -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
@@ -15,6 +15,7 @@ module Askable
15
15
  colored_say e.inspect
16
16
  exit 0
17
17
  end
18
+ answer
18
19
  end
19
20
 
20
21
  def ask_with_help(opts={}, &block)
@@ -56,13 +57,9 @@ module Askable
56
57
 
57
58
  def choose(str, choices={}, opts={}, &block)
58
59
  colored_say(str)
59
- choices.each do |k,v|
60
- colored_say("#{k}) #{v}")
61
- end
62
- colored_print((opts[:prompt] || "> "))
63
- pick = gets.chomp.to_i
64
- yield choices[pick] if block
65
- choices[pick]
60
+ answer = ask(choices)
61
+ yield answer if block
62
+ answer
66
63
  end
67
64
 
68
65
  def wait
@@ -130,6 +127,8 @@ module Askable
130
127
  case @question
131
128
  when String
132
129
  ask_string
130
+ when Hash
131
+ ask_hash
133
132
  when Array
134
133
  ask_array
135
134
  end
@@ -150,5 +149,15 @@ module Askable
150
149
  num = (@input.gets).to_i rescue colored_say("<red>Invalid input, must be a number between 1 and #{@question.size + 1}")
151
150
  @answer = @question[num-1]
152
151
  end
152
+
153
+ def ask_hash
154
+ @question.sort.each do |k,v|
155
+ colored_say("#{k}) #{v}")
156
+ end
157
+ colored_print((@opts[:prompt] || "> "))
158
+ pick = @input.gets.to_i
159
+ @answer = @question[pick]
160
+ end
161
+
153
162
  end
154
163
  end
@@ -37,6 +37,7 @@ module PoolParty
37
37
  # - stack
38
38
  def run_in_context(o={}, &block)
39
39
  proc = Proc.new do
40
+ set_vars_from_options(:name => o[:name]) if o.has_key?(:name) # Name MUST be set first
40
41
  set_vars_from_options(o)
41
42
  instance_eval &block if block
42
43
  end
@@ -127,12 +128,12 @@ module PoolParty
127
128
  # to create edges on the graph
128
129
  def resources_graph(force=false)
129
130
  return @resources_graph if @resources_graph && !force
130
- result = Digraph.new
131
-
132
- add_ordered_resources_to_result(resources, result)
131
+ result = Digraph.new
133
132
 
134
133
  create_graph(resources, nil, result)
135
134
 
135
+ add_ordered_resources_to_result(resources, result)
136
+
136
137
  @resources_graph = result
137
138
  end
138
139
 
@@ -141,7 +142,7 @@ module PoolParty
141
142
  arr_of_resources = resources.zip_offset(1)
142
143
 
143
144
  arr_of_resources.each do |first, second|
144
- result.add_edge!(first, second)
145
+ result.add_edge!(first, second) unless result.edge?(first, second) or result.edge?(second, first)
145
146
  add_ordered_resources_to_result(first.resources, result)
146
147
  end
147
148
  end
@@ -200,9 +201,9 @@ module PoolParty
200
201
 
201
202
  # The clouds.rb file
202
203
  def clouds_dot_rb_file(n=nil); self.class.clouds_dot_rb_file(n); end
203
- def self.clouds_dot_rb_file(n=nil)
204
- Pool.clouds_dot_rb_file(n)
205
- end
204
+ def self.clouds_dot_rb_file(n=nil);Pool.clouds_dot_rb_file(n);end
205
+ def clouds_dot_rb_dir(n=nil); self.class.clouds_dot_rb_dir(n);end
206
+ def self.clouds_dot_rb_dir(n=nil); Pool.clouds_dot_rb_dir(n);end
206
207
 
207
208
  # If the method is missing from ourself, check the Default
208
209
  # class for the corresponding method.
@@ -26,6 +26,12 @@ module PoolParty
26
26
  callback_block do |cld, callback|
27
27
  end
28
28
 
29
+ def before_compile
30
+ add_monitoring_stack_if_needed
31
+
32
+ validate_all_resources
33
+ end
34
+
29
35
  # Freeze the cloud_name so we can't modify it at all, set the plugin_directory
30
36
  # call and run instance_eval on the block and then call the after_create callback
31
37
  def initialize(n, o={}, &block)
@@ -57,7 +63,7 @@ module PoolParty
57
63
  end
58
64
 
59
65
  # Cloud provider methods
60
- 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
61
67
  def run_instance(o={}); cloud_provider.run_instance(o);end
62
68
  def terminate_instance!(o={}); cloud_provider.terminate_instance!(o);end
63
69
  def describe_instances(o={}); cloud_provider.describe_instances(o);end
@@ -83,7 +89,7 @@ module PoolParty
83
89
 
84
90
  # 1.) Launches a new instance,
85
91
  # 2.) Waits for the instance to get an ip address
86
- # 3.) Waits for port 22 to be open
92
+ # 3.) Waits for port ssh_port to be open
87
93
  # 4.) Calls call_after_launch_instance callbacks
88
94
  # 5.) Executes passed &block, if any
89
95
  # 6.) Returns the new instance object
@@ -94,7 +100,7 @@ module PoolParty
94
100
  instance.cloud = self
95
101
  @instance = instance
96
102
  #wait for an ip and then wait for ssh port, then configure instance
97
- 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)
98
104
  callback :after_launch_instance
99
105
  instance.callback :before_bootstrap
100
106
  instance.bootstrap!
@@ -105,7 +111,7 @@ module PoolParty
105
111
  block.call(instance) if block
106
112
  instance
107
113
  else
108
- raise StandardError.new("Instance port 22 not available")
114
+ raise StandardError.new("Instance port #{ssh_port} not available")
109
115
  end
110
116
  instance.refresh!
111
117
  instance
@@ -122,7 +128,7 @@ module PoolParty
122
128
 
123
129
  # convenience method to loop thru all the nodes and configure them
124
130
  def configure!(opts={}, threaded=true)
125
- nodes.collect{|n| n.configure!}
131
+ nodes.collect{|n| n.configure! }
126
132
  end
127
133
 
128
134
  # Run command/s on all nodes in the cloud.
@@ -173,12 +179,31 @@ module PoolParty
173
179
  end
174
180
  end
175
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
+
176
195
  # Take the cloud's resources and compile them down using
177
196
  # the defined (or the default dependency_resolver, chef)
178
197
  def compile(caller=nil)
198
+ callback :before_compile
179
199
  FileUtils.mkdir_p tmp_path unless File.directory?(tmp_path)
180
- ddputs("Compiling cloud #{self.name} to #{tmp_path/"etc"/"#{dependency_resolver_name}"}")
181
- dependency_resolver.compile_to(ordered_resources, tmp_path/"etc"/"#{dependency_resolver_name}", caller)
200
+ ddputs <<-EOE
201
+ Compiling cloud #{self.name} to #{tmp_path/"etc"/"#{dependency_resolver_name}"}
202
+ number of resources: #{ordered_resources.size}
203
+ EOE
204
+ out = dependency_resolver.compile_to(ordered_resources, tmp_path/"etc"/"#{dependency_resolver_name}", caller)
205
+ callback :after_compile
206
+ out
182
207
  end
183
208
 
184
209
  # Get the os of the first node if it was not explicity defined, we'll assume they are
@@ -242,5 +267,50 @@ module PoolParty
242
267
  end
243
268
  end
244
269
 
270
+ def validate_all_resources
271
+ ddputs("Validating all the resources")
272
+ [:ensure_not_cyclic, :ensure_meta_fun_are_resources].each do |meth|
273
+ self.send meth
274
+ end
275
+ end
276
+
277
+ def ensure_not_cyclic
278
+ if resources_graph.cyclic?
279
+ cycles = []
280
+
281
+ resources_graph.edges.each do |edge|
282
+ if resources_graph.adjacent?(edge.source, edge.target) && resources_graph.adjacent?(edge.target, edge.source) && !cycles.include?(edge.source)
283
+ cycles << "#{edge.source.class}(#{edge.source.name}) depends on #{edge.target.class}(#{edge.target.name})"
284
+ end
285
+ end
286
+ msg =<<-EOE
287
+
288
+ Your resource graph is cyclic. Two resources depend on each other, Cannot decide which resource
289
+ to go first. Dying instead. Correct this and then try again.
290
+
291
+ #{cycles.join("\n ")}
292
+
293
+ Hint: You can see the resource graph by generating it with:
294
+ cloud compile -g name
295
+
296
+ EOE
297
+ raise PoolPartyError.create("CyclicResourceGraphError", msg)
298
+ end
299
+ end
300
+
301
+ def ensure_meta_fun_are_resources
302
+ resources.each do |res|
303
+
304
+ if res.meta_notifies
305
+ res.meta_notifies.each do |ty, arr|
306
+ arr.each do |nm, action|
307
+ raise PoolPartyError.create("ResourceNotFound", "A resource required for #{ty}(#{nm}) was not found: #{ty}(#{nm}). Please make sure you've specified this in your configuration.") unless get_resource(ty, nm)
308
+ end
309
+ end
310
+ end
311
+
312
+ end
313
+ end
314
+
245
315
  end
246
316
  end
@@ -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",
@@ -15,7 +15,7 @@ module PoolParty
15
15
  steps.each {|c| self.__send__ c.to_sym }
16
16
  self.__send__ :closing_message
17
17
  rescue Exception => e
18
- # colored_say e.inspect
18
+ colored_say e.inspect
19
19
  colored_say exit_msg
20
20
  ensure
21
21
  Colors.reset!
@@ -35,7 +35,7 @@ First, we'll setup your environment so using PoolParty will be a <blue>breeze</b
35
35
  <yellow>Cancelled PoolParty installation</yellow>
36
36
 
37
37
  You can always restart this by typing:
38
- <blue>install-poolparty</blue>
38
+ <blue>cloud setup</blue>
39
39
 
40
40
  <line>
41
41
  EOE
@@ -97,8 +97,12 @@ irc.freenode.net / #poolpartyrb
97
97
  def self.all
98
98
  @all ||= []
99
99
  end
100
-
101
-
100
+
101
+ def self.find_by_name(nm)
102
+ all.detect do |i|
103
+ i.name =~ /#{nm}/i
104
+ end
105
+ end
102
106
  end
103
107
  end
104
108