poolparty 1.4.8 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :patch: 8
2
+ :patch: 0
3
3
  :major: 1
4
4
  :build:
5
- :minor: 4
5
+ :minor: 5
data/bin/cloud-show CHANGED
@@ -38,10 +38,17 @@ EOS
38
38
  load_balancers = cld.cloud_provider.load_balancers.first.running_load_balancers.map {|a| a[:dns_name]}
39
39
  msg << "Load balancers: #{load_balancers.join("\n\t\t\t")}"
40
40
  end
41
+
42
+ if cld.rds_instances.size > 0
43
+ available = cld.cloud_provider.available_rds_instances.map{|r| "#{r.instance_id}\t#{r.current_status.Endpoint.Address}" }
44
+ available.unshift 'RDS Instances:'
45
+
46
+ msg << available.join("\n\t\t\t")
47
+ end
41
48
 
42
49
  puts msg.flatten
43
50
 
44
51
  end
45
52
 
46
53
  end
47
- end
54
+ end
@@ -27,15 +27,48 @@ module CloudProviders
27
27
  def run(commands, o={})
28
28
  ssh(commands)
29
29
  end
30
-
30
+
31
+ def shell_escape(str)
32
+ String(str).gsub(/(?=["'\\$])/n, '\\').
33
+ gsub(/\n/, "'\n'").
34
+ sub(/^$/, "''")
35
+ end
36
+
31
37
  def ssh( commands=[], extra_ssh_ops={})
32
- commands = commands.compact.join(' && ') if commands.is_a?(Array)
33
- cmd_string = "ssh #{user}@#{host} #{ssh_options(extra_ssh_ops)}"
38
+ # Get the environment hash out of
39
+ # the extra_ssh_ops and then delete
40
+ # the element
41
+ env = extra_ssh_ops[:env] || {}
42
+ extra_ssh_ops.delete :env
43
+
44
+ # Decide to use sudo or not
45
+ do_sudo = true
46
+ if extra_ssh_ops.has_key? :do_sudo
47
+ do_sudo = extra_ssh_ops[:do_sudo]
48
+ extra_ssh_ops.delete :do_sudo
49
+ end
50
+
51
+ envstring = env.collect {|k,v| "#{k}=#{v}"}.join ' && '
52
+ envstring += " && " unless envstring.size == 0
53
+ ssh_string = "ssh #{user}@#{host} #{ssh_options(extra_ssh_ops)}"
54
+
34
55
  if commands.empty?
35
56
  #TODO: replace this with a IO.popen call with read_nonblocking to show progress, and accept input
36
- Kernel.system(cmd_string)
57
+ Kernel.system(ssh_string)
37
58
  else
38
- system_run(cmd_string+" '#{commands}'")
59
+ r = nil
60
+ commands.each do |command|
61
+
62
+ cmd = "#{envstring}#{command}"
63
+ if do_sudo
64
+ sudocmd = %Q% sudo sh -c "#{shell_escape cmd}" %
65
+ else
66
+ sudocmd = cmd
67
+ end
68
+
69
+ r = system_run ssh_string + %Q% "#{shell_escape sudocmd}"%
70
+ end
71
+ r
39
72
  end
40
73
  end
41
74
 
@@ -46,7 +79,7 @@ module CloudProviders
46
79
  def ssh_options(opts={})
47
80
  return @ssh_options if @ssh_options && opts.empty?
48
81
  ssh_opts = {"-i" => keypair.full_filepath,
49
- "-o" =>"StrictHostKeyChecking=no"
82
+ "-o" =>"StrictHostKeyChecking=no",
50
83
  }.merge(opts)
51
84
  @ssh_options = ssh_opts.collect{ |k,v| "#{k} #{v}"}.join(' ')
52
85
  end
@@ -55,7 +88,8 @@ module CloudProviders
55
88
  raise StandardError.new("You must pass a :source=>uri option to rsync") unless opts[:source]
56
89
  destination_path = opts[:destination] || opts[:source]
57
90
  rsync_opts = opts[:rsync_opts] || '-va'
58
- cmd_string = "rsync -L -e 'ssh #{ssh_options}' #{rsync_opts} #{opts[:source]} #{user}@#{host}:#{destination_path}"
91
+ rsync_opts += %q% --rsync-path="sudo rsync" --exclude=.svn --exclude=.git --exclude=.cvs %
92
+ cmd_string = "rsync -L -e 'ssh #{ssh_options}' #{rsync_opts} #{opts[:source]} #{user}@#{host}:#{destination_path}"
59
93
  out = system_run(cmd_string)
60
94
  out
61
95
  end
@@ -106,4 +140,4 @@ module CloudProviders
106
140
  end
107
141
 
108
142
  end
109
- end
143
+ end
@@ -326,6 +326,10 @@ module CloudProviders
326
326
  rds_instances << RdsInstance.new(given_name, sub_opts.merge(o || {}), &block)
327
327
  end
328
328
 
329
+ def available_rds_instances
330
+ rds_instances.select{|r| r.available? }
331
+ end
332
+
329
333
  # Proxy to the raw Grempe amazon-aws @ec2 instance
330
334
  def ec2
331
335
  @ec2 ||= begin
@@ -145,7 +145,7 @@ module CloudProviders
145
145
  :user_data => user_data,
146
146
  :kernel_id => kernel_id,
147
147
  :ramdisk_id => ramdisk_id,
148
- :block_device_mappings => block_device_mappings
148
+ :block_device_mapping => block_device_mapping
149
149
  })
150
150
  rescue Exception => e
151
151
  puts <<-EOE
@@ -424,4 +424,4 @@ module CloudProviders
424
424
  "#{(measure_names[measure] || measure)}-#{name}" || name
425
425
  end
426
426
  end
427
- end
427
+ end
@@ -32,7 +32,7 @@ module CloudProviders
32
32
 
33
33
  # get volumes that are not attached
34
34
  def free_volumes(availability_zone)
35
- @volumes.select{|vol| vol.available? and vol.availability_zone == availability_zone}
35
+ @volumes.flatten.select{|vol| vol.available? and vol.availability_zone == availability_zone}
36
36
  end
37
37
  # Get a free volume from existing volumes in group or create a new one
38
38
  def get_free_volume(availability_zone)
@@ -33,6 +33,22 @@ module CloudProviders
33
33
  delete_rds_instance!
34
34
  end
35
35
 
36
+ def current_status
37
+ rds_instances.detect{|i| i.DBInstanceIdentifier == instance_id }
38
+ end
39
+
40
+ def exists?
41
+ ! current_status.nil?
42
+ end
43
+
44
+ def available?
45
+ exists? && current_status.DBInstanceStatus == 'available'
46
+ end
47
+
48
+ def instance_id
49
+ name.to_s
50
+ end
51
+
36
52
  private
37
53
 
38
54
  def authorizations
@@ -53,11 +69,7 @@ module CloudProviders
53
69
  end
54
70
 
55
71
  def should_create_rds_instance?
56
- rds_instances.select{|i| i.DBInstanceIdentifier == instance_id }.empty?
57
- end
58
-
59
- def instance_id
60
- name.to_s
72
+ ! exists?
61
73
  end
62
74
 
63
75
  def create_rds_instance!
@@ -107,4 +119,4 @@ module CloudProviders
107
119
  end
108
120
  end
109
121
  end
110
- end
122
+ end
@@ -37,7 +37,8 @@ module CloudProviders
37
37
  end
38
38
 
39
39
  def chef_bootstrapped?
40
- @chef_bootstrapped ||= !ssh(["gem list | grep chef"]).empty?
40
+ # do_sudo is false cause we want to capture the return code of the call
41
+ @chef_bootstrapped ||= !ssh(["gem list | grep chef"], :do_sudo => false).empty?
41
42
  end
42
43
 
43
44
  def bootstrap_chef!
@@ -45,19 +46,21 @@ module CloudProviders
45
46
  ssh([
46
47
  'apt-get update',
47
48
  'apt-get autoremove -y',
48
- 'apt-get install -y ruby ruby-dev rubygems git-core',
49
+ 'apt-get install -y ruby ruby-dev rubygems git-core libopenssl-ruby',
49
50
  'gem sources -a http://gems.opscode.com',
50
- 'gem install chef ohai --no-rdoc --no-ri' ] +
51
- bootstrap_gems.collect { |gem| "gem install #{gem} --no-rdoc --no-ri" } )
51
+ 'gem install chef ohai --no-rdoc --no-ri' ])
52
52
  end
53
+ ssh(bootstrap_gems.collect { |gem| "gem install #{gem} --no-rdoc --no-ri" } )
53
54
  end
54
55
 
55
56
  def run_chef!
56
57
  chef_solo_cmd = <<-CMD
57
- GEM_BIN=$(gem env | grep "EXECUTABLE DIRECTORY" | awk "{print \\$4}") \
58
- && $GEM_BIN/chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb
58
+ $GEM_BIN/chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb
59
59
  CMD
60
- ssh([chef_solo_cmd.strip.squeeze(' ')])
60
+ envhash = {
61
+ :GEM_BIN => %q%$(gem env | grep "EXECUTABLE DIRECTORY" | awk "{print \\$4}")%
62
+ }
63
+ ssh([chef_solo_cmd.strip.squeeze(' ')], :env => envhash )
61
64
  end
62
65
 
63
66
  def run
@@ -64,10 +64,34 @@ You did not specify a cloud provider in your clouds.rb. Make sure you have a blo
64
64
  def chef_attributes(hsh={}, &block)
65
65
  @chef_attributes ||= ChefAttribute.new(hsh, &block)
66
66
  end
67
+
68
+ def chef_override_attributes(hsh={}, &block)
69
+ @chef_override_attributes ||= ChefAttribute.new(hsh, &block)
70
+ end
67
71
 
72
+ # Adds a chef recipe to the cloud
73
+ #
74
+ # The hsh parameter is inserted into the chef_override_attributes.
75
+ # The insertion is performed as follows. If
76
+ # the recipe name = "foo::bar" then effectively the call is
77
+ #
78
+ # chef_override_attributes.merge! { :foo => { :bar => hsh } }
68
79
  def recipe(recipe_name, hsh={})
69
80
  _recipes << recipe_name unless _recipes.include?(recipe_name)
70
- _attributes.merge!(recipe_name => hsh) unless hsh.empty?
81
+
82
+ head = {}
83
+ tail = head
84
+ recipe_name.split("::").each do |key|
85
+ unless key == "default"
86
+ n = {}
87
+ tail[key] = n
88
+ tail = n
89
+ end
90
+ end
91
+ tail.replace hsh
92
+
93
+ chef_override_attributes.merge!(head) unless hsh.empty?
94
+
71
95
  end
72
96
 
73
97
  def recipes(*recipes)
@@ -81,16 +105,18 @@ You did not specify a cloud provider in your clouds.rb. Make sure you have a blo
81
105
  def _recipes
82
106
  @_recipes ||= []
83
107
  end
84
- def _attributes
85
- @_attributes ||= {}
86
- end
87
108
 
88
109
  # The NEW actual chef resolver.
89
110
  def build_tmp_dir
90
111
  base_directory = tmp_path/"etc"/"chef"
112
+ FileUtils.rm_rf base_directory
91
113
  puts "Copying the chef-repo into the base directory from #{chef_repo}"
92
114
  FileUtils.mkdir_p base_directory/"roles"
93
115
  if File.directory?(chef_repo)
116
+ if File.exist?(base_directory)
117
+ # First remove the directory
118
+ FileUtils.remove_entry base_directory, :force => true
119
+ end
94
120
  FileUtils.cp_r "#{chef_repo}/.", base_directory
95
121
  else
96
122
  raise "#{chef_repo} chef repo directory does not exist"
@@ -114,12 +140,23 @@ log_level :info
114
140
  end
115
141
 
116
142
  def write_chef_role_json(to=tmp_path/"etc"/"chef"/"dna.json")
143
+
144
+ # Add the parent name and the name of the cloud to
145
+ # the role for easy access in recipes.
146
+ pp = {
147
+ :poolparty => {
148
+ :parent_name => parent.name,
149
+ :name => name,
150
+ }
151
+ }
152
+
153
+ chef_override_attributes.merge! pp
117
154
  ca = ChefAttribute.new({
118
155
  :name => name,
119
156
  :json_class => "Chef::Role",
120
157
  :chef_type => "role",
121
158
  :default_attributes => chef_attributes.init_opts,
122
- :override_attributes => {},
159
+ :override_attributes => chef_override_attributes.init_opts,
123
160
  :description => description
124
161
  })
125
162
  ca.to_dna _recipes.map {|a| File.basename(a) }, to
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poolparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.8
4
+ version: 1.5.0
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: 2010-01-27 00:00:00 -08:00
14
+ date: 2010-02-18 00:00:00 -08:00
15
15
  default_executable:
16
16
  dependencies: []
17
17