poolparty 1.4.8 → 1.5.0

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