poolparty 1.6.4 → 1.6.5
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 +1 -1
- data/bin/cloud +1 -0
- data/lib/cloud_providers/connections.rb +14 -2
- data/lib/cloud_providers/ec2/ec2.rb +28 -17
- data/lib/cloud_providers/ec2/ec2_instance.rb +13 -2
- data/lib/cloud_providers/remote_instance.rb +4 -3
- data/lib/keypair.rb +31 -12
- data/lib/poolparty/chef.rb +78 -12
- data/lib/poolparty/chef_client.rb +69 -11
- data/lib/poolparty/chef_solo.rb +3 -7
- data/lib/poolparty.rb +1 -0
- data/test/fixtures/keys/pem_key.pem +27 -0
- data/test/fixtures/keys/pem_pub_key.pem +8 -0
- data/test/lib/poolparty/keypair_test.rb +21 -1
- metadata +3 -1
data/VERSION.yml
CHANGED
data/bin/cloud
CHANGED
|
@@ -35,6 +35,9 @@ module CloudProviders
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def ssh( commands=[], extra_ssh_ops={})
|
|
38
|
+
# commands can be single commands, as well as array
|
|
39
|
+
commands = [commands] unless commands.respond_to? :each
|
|
40
|
+
|
|
38
41
|
# Get the environment hash out of
|
|
39
42
|
# the extra_ssh_ops and then delete
|
|
40
43
|
# the element
|
|
@@ -44,12 +47,12 @@ module CloudProviders
|
|
|
44
47
|
extra_ssh_ops.delete :env
|
|
45
48
|
|
|
46
49
|
# Decide to use sudo or not
|
|
47
|
-
do_sudo =
|
|
50
|
+
do_sudo = user!="root"
|
|
51
|
+
|
|
48
52
|
if extra_ssh_ops.has_key? :do_sudo
|
|
49
53
|
do_sudo = extra_ssh_ops[:do_sudo]
|
|
50
54
|
extra_ssh_ops.delete :do_sudo
|
|
51
55
|
end
|
|
52
|
-
do_sudo=user!="root"
|
|
53
56
|
|
|
54
57
|
envstring = env.collect {|k,v| "#{k}=#{v}"}.join ' && '
|
|
55
58
|
envstring += " && " unless envstring.size == 0
|
|
@@ -74,6 +77,15 @@ module CloudProviders
|
|
|
74
77
|
r
|
|
75
78
|
end
|
|
76
79
|
end
|
|
80
|
+
|
|
81
|
+
# remove hostname and corresponding from known_hosts file. Avoids warning when reusing elastic_ip, and
|
|
82
|
+
# less likely, if amazone reassigns ip. By default removes both dns_name and ip
|
|
83
|
+
def ssh_cleanup_known_hosts!(hosts=[host, public_ip])
|
|
84
|
+
hosts = [hosts] unless hosts.respond_to? :each
|
|
85
|
+
hosts.compact.each do |name|
|
|
86
|
+
system_run "ssh-keygen -R %s" % name
|
|
87
|
+
end
|
|
88
|
+
end
|
|
77
89
|
|
|
78
90
|
# Take a hash of options and join them into a string, combined with default options.
|
|
79
91
|
# Default options are -o StrictHostKeyChecking=no -i keypair.full_filepath -l user
|
|
@@ -75,7 +75,6 @@ module CloudProviders
|
|
|
75
75
|
|
|
76
76
|
default_options(
|
|
77
77
|
:instance_type => 'm1.small',
|
|
78
|
-
:addressing_type => "public",
|
|
79
78
|
:availability_zones => ["us-east-1a"],
|
|
80
79
|
:user_id => default_user_id,
|
|
81
80
|
:private_key => default_private_key,
|
|
@@ -89,10 +88,12 @@ module CloudProviders
|
|
|
89
88
|
:min_count => 1,
|
|
90
89
|
:max_count => 1,
|
|
91
90
|
:user_data => '',
|
|
92
|
-
:addressing_type => nil,
|
|
93
91
|
:kernel_id => nil,
|
|
94
92
|
:ramdisk_id => nil,
|
|
95
|
-
:block_device_mapping => [{}]
|
|
93
|
+
:block_device_mapping => [{}],
|
|
94
|
+
:disable_api_termination => nil,
|
|
95
|
+
:instance_initiated_shutdown_behavior => nil,
|
|
96
|
+
:subnet_id => nil
|
|
96
97
|
)
|
|
97
98
|
|
|
98
99
|
# Called when the create command is called on the cloud
|
|
@@ -173,6 +174,7 @@ module CloudProviders
|
|
|
173
174
|
end
|
|
174
175
|
|
|
175
176
|
assign_elastic_ips
|
|
177
|
+
cleanup_ssh_known_hosts!
|
|
176
178
|
puts "Attaching EBS volumes"
|
|
177
179
|
assign_ebs_volumes # Assign EBS volumes
|
|
178
180
|
end
|
|
@@ -196,7 +198,10 @@ module CloudProviders
|
|
|
196
198
|
:availability_zone => availability_zones.first,
|
|
197
199
|
:base64_encoded => true,
|
|
198
200
|
:cloud => cloud,
|
|
199
|
-
:block_device_mapping => block_device_mapping
|
|
201
|
+
:block_device_mapping => block_device_mapping,
|
|
202
|
+
:disable_api_termination => disable_api_termination,
|
|
203
|
+
:instance_initiated_shutdown_behavior => instance_initiated_shutdown_behavior,
|
|
204
|
+
:subnet_id => subnet_id,
|
|
200
205
|
})
|
|
201
206
|
progress_bar_until("Waiting for node to launch...") do
|
|
202
207
|
wait_for_node(e)
|
|
@@ -223,7 +228,9 @@ module CloudProviders
|
|
|
223
228
|
def contract_by(num=1)
|
|
224
229
|
raise RuntimeError, "Contracting instances by #{num} will lower the number of instances below specified minimum" unless nodes.size - num > minimum_instances
|
|
225
230
|
num.times do |i|
|
|
226
|
-
|
|
231
|
+
node = nodes[-num]
|
|
232
|
+
id = node.instance_id
|
|
233
|
+
node.ssh_cleanup_known_hosts!
|
|
227
234
|
Ec2Instance.terminate!(:instance_id => id, :cloud => cloud)
|
|
228
235
|
end
|
|
229
236
|
reset!
|
|
@@ -245,17 +252,11 @@ module CloudProviders
|
|
|
245
252
|
end
|
|
246
253
|
|
|
247
254
|
def configure_nodes!(tmp_path=nil)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
nodes.each do |node|
|
|
254
|
-
next unless node.in_service?
|
|
255
|
-
node.cloud_provider = self
|
|
256
|
-
node.rsync_dir(tmp_path) if tmp_path
|
|
257
|
-
node.run_chef!
|
|
258
|
-
end
|
|
255
|
+
# removed duplicated code (now configure_nodes! invokes
|
|
256
|
+
# node.bootstrap_chef!, while old version did not, but I believe
|
|
257
|
+
# this is harmless)
|
|
258
|
+
bootstrap_nodes!(tmp_path)
|
|
259
|
+
|
|
259
260
|
ebs_volume_groups.each do |vol_grp|
|
|
260
261
|
vol_grp.verify_attachments nodes
|
|
261
262
|
end
|
|
@@ -284,7 +285,17 @@ module CloudProviders
|
|
|
284
285
|
end
|
|
285
286
|
end
|
|
286
287
|
end
|
|
287
|
-
|
|
288
|
+
|
|
289
|
+
def cleanup_ssh_known_hosts!(nodes_to_cleanup=nodes,
|
|
290
|
+
even_unavailable=false)
|
|
291
|
+
puts "cleaning up .ssh/known_hosts"
|
|
292
|
+
nodes_to_cleanup.find_all do |node|
|
|
293
|
+
even_unavailable || node.ssh_available?
|
|
294
|
+
end.each do |node|
|
|
295
|
+
node.ssh_cleanup_known_hosts!
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
288
299
|
def nodes
|
|
289
300
|
all_nodes.select {|i| i.in_service? }#describe_instances.select {|i| i.in_service? && security_groups.include?(i.security_groups) }
|
|
290
301
|
end
|
|
@@ -10,7 +10,10 @@ module CloudProviders
|
|
|
10
10
|
:key_name => nil,
|
|
11
11
|
:launch_time => nil,
|
|
12
12
|
:availability_zones => [],
|
|
13
|
-
:block_device_mapping => [{}]
|
|
13
|
+
:block_device_mapping => [{}],
|
|
14
|
+
:disable_api_termination => nil,
|
|
15
|
+
:instance_initiated_shutdown_behavior => nil,
|
|
16
|
+
:subnet_id => nil
|
|
14
17
|
)
|
|
15
18
|
|
|
16
19
|
def initialize(raw_response={})
|
|
@@ -27,6 +30,9 @@ module CloudProviders
|
|
|
27
30
|
self.availability_zones = raw_response["placement"]["availabilityZone"] rescue nil
|
|
28
31
|
self.status = raw_response["instanceState"]["name"] rescue nil
|
|
29
32
|
self.block_device_mapping = raw_response["blockDeviceMapping"] rescue nil
|
|
33
|
+
self.disable_api_termination = raw_response["disableApiTermination"] rescue nil
|
|
34
|
+
self.instance_initiated_shutdown_behavior = raw_response["instance_initiated_shutdown_behavior"] rescue nil
|
|
35
|
+
self.subnet_id = raw_response["subnetId"] rescue nil
|
|
30
36
|
super
|
|
31
37
|
end
|
|
32
38
|
|
|
@@ -43,7 +49,12 @@ module CloudProviders
|
|
|
43
49
|
end
|
|
44
50
|
|
|
45
51
|
def ssh_available?
|
|
46
|
-
cloud.security_groups.map {|a|
|
|
52
|
+
cloud.security_groups.map {|a|
|
|
53
|
+
a.authorizes.map {|t| t.from_port.to_i }.flatten
|
|
54
|
+
}.flatten.include?(22) and
|
|
55
|
+
reachable? and
|
|
56
|
+
in_service? and
|
|
57
|
+
keypair and keypair.exists?
|
|
47
58
|
end
|
|
48
59
|
|
|
49
60
|
def in_service?
|
|
@@ -37,12 +37,13 @@ module CloudProviders
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def chef_bootstrapped?
|
|
40
|
-
|
|
41
|
-
@chef_bootstrapped ||= cloud.chef.node_bootsrapped?(self)
|
|
40
|
+
@chef_bootstrapped ||= cloud.chef.node_bootstrapped?(self)
|
|
42
41
|
end
|
|
43
42
|
|
|
43
|
+
# TODO: chef_bootstrapped? should go away, since Chef#node_bootstrap!
|
|
44
|
+
# already checks node_bootstrap!. There is a force flag as well.
|
|
44
45
|
def bootstrap_chef!
|
|
45
|
-
cloud.chef.node_bootstrap(self)
|
|
46
|
+
cloud.chef.node_bootstrap!(self)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def run_chef!
|
data/lib/keypair.rb
CHANGED
|
@@ -5,20 +5,25 @@ class Keypair
|
|
|
5
5
|
|
|
6
6
|
include SearchablePaths
|
|
7
7
|
has_searchable_paths(:prepend_paths => [Dir.pwd, '/etc/poolparty/keys', "#{ENV["HOME"]}/.ssh/", "#{ENV["HOME"]}/.ec2/", ENV['EC2_CONFIG_DIR']])
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
# Amazon will not append suffix, but public key may have '.pem' suffix
|
|
10
|
+
SEARCH_SUFFIXES = %w( .pem )
|
|
11
|
+
|
|
9
12
|
attr_accessor :filepath
|
|
10
13
|
attr_reader :extra_paths, :opts
|
|
14
|
+
attr_reader :search_suffixes
|
|
11
15
|
|
|
12
16
|
# Create a new key that defaults to id_rsa as the name.
|
|
13
17
|
def initialize(fpath, extra_paths=[], opts={})
|
|
14
18
|
@filepath = fpath
|
|
15
19
|
@opts = opts
|
|
16
20
|
@extra_paths = extra_paths.map {|a| File.expand_path(a) }
|
|
21
|
+
@search_suffixes = SEARCH_SUFFIXES
|
|
17
22
|
end
|
|
18
23
|
|
|
19
|
-
# If the full_filepath is nil, then the key doesn't exist
|
|
24
|
+
# If the full_filepath is nil or false, then the key doesn't exist
|
|
20
25
|
def exists?
|
|
21
|
-
full_filepath
|
|
26
|
+
!! full_filepath
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
# Read the content of the key
|
|
@@ -29,13 +34,9 @@ class Keypair
|
|
|
29
34
|
# Returns the full_filepath of the key. If a full filepath is passed, we just return the expanded filepath
|
|
30
35
|
# for the keypair, otherwise query where it is against known locations
|
|
31
36
|
def full_filepath
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
else
|
|
36
|
-
search_in_known_locations(filepath, extra_paths)
|
|
37
|
-
end
|
|
38
|
-
@full_filepath ? @full_filepath : false
|
|
37
|
+
@full_filepath ||=
|
|
38
|
+
find_file_in_path_with_suffix(filepath, extra_paths,
|
|
39
|
+
search_suffixes) || false
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
def to_s
|
|
@@ -99,6 +100,24 @@ class Keypair
|
|
|
99
100
|
raise StandardError.new("#{filepath} key file cannot be found") unless filepath.nil?
|
|
100
101
|
end
|
|
101
102
|
end
|
|
103
|
+
|
|
104
|
+
# try filename with suffix and without suffixes.
|
|
105
|
+
# Checks all paths without suffix first, then try all paths for all suffixes.
|
|
106
|
+
def find_file_in_path_with_suffix(file, extra_paths, suffixes=[],
|
|
107
|
+
try_wo_suffix=true)
|
|
108
|
+
suffixes_to_try = suffixes.dup
|
|
109
|
+
suffixes_to_try.unshift '' if try_wo_suffix
|
|
110
|
+
|
|
111
|
+
suffixes_to_try.map {|s| file + s }.each do |suffixed|
|
|
112
|
+
fullpath = if File.file?(File.expand_path(suffixed))
|
|
113
|
+
::File.expand_path(suffixed)
|
|
114
|
+
else
|
|
115
|
+
search_in_known_locations(suffixed, extra_paths)
|
|
116
|
+
end
|
|
117
|
+
return fullpath if fullpath
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
nil
|
|
121
|
+
end
|
|
102
122
|
|
|
103
|
-
|
|
104
|
-
end
|
|
123
|
+
end
|
data/lib/poolparty/chef.rb
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
module PoolParty
|
|
2
2
|
class Chef < Base
|
|
3
|
+
|
|
4
|
+
BOOTSTRAP_PACKAGES = %w( ruby ruby1.8-dev libopenssl-ruby1.8 rdoc
|
|
5
|
+
ri irb build-essential wget ssl-cert rubygems git-core rake
|
|
6
|
+
librspec-ruby libxml-ruby zlib1g-dev libxml2-dev )
|
|
7
|
+
# thin couchdb
|
|
8
|
+
BOOTSTRAP_GEMS = %w( chef )
|
|
9
|
+
|
|
10
|
+
# we dont specifically install these binaries, they installed by
|
|
11
|
+
# packages and gems above, but we check for them
|
|
12
|
+
BOOTSTRAP_BINS = %w( gem chef-solo chef-client )
|
|
13
|
+
BOOTSTRAP_DIRS = %w( /var/log/chef /var/cache/chef /var/run/chef )
|
|
14
|
+
|
|
15
|
+
def compile!
|
|
16
|
+
build_tmp_dir
|
|
17
|
+
end
|
|
18
|
+
|
|
3
19
|
def self.types
|
|
4
20
|
return [:solo,:client]
|
|
5
21
|
end
|
|
@@ -48,26 +64,76 @@ module PoolParty
|
|
|
48
64
|
end
|
|
49
65
|
|
|
50
66
|
def node_run!(remote_instance)
|
|
67
|
+
node_stop!(remote_instance)
|
|
68
|
+
node_configure!(remote_instance)
|
|
69
|
+
|
|
51
70
|
envhash = {
|
|
52
71
|
:GEM_BIN => %q%$(gem env | grep "EXECUTABLE DIRECTORY" | awk "{print \\$4}")%
|
|
53
72
|
}
|
|
54
|
-
|
|
73
|
+
cmds = chef_cmd
|
|
74
|
+
cmds = [cmds] unless cmds.respond_to? :each
|
|
75
|
+
|
|
76
|
+
remote_instance.ssh(cmds.map{|c| c.strip.squeeze(' ')}, :env => envhash )
|
|
55
77
|
end
|
|
56
78
|
|
|
57
|
-
def
|
|
58
|
-
|
|
59
|
-
remote_instance.ssh(['if [ ! -n "$(gem list 2>/dev/null | grep chef)" ]; then echo "chef installed"; fi'], :do_sudo => false).empty? rescue false
|
|
79
|
+
def node_stop!(remote_instance)
|
|
80
|
+
remote_instance.ssh("killall -q chef-client chef-solo; [ -f /etc/init.d/chef-client ] && invoke-rc.d chef-client stop")
|
|
60
81
|
end
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'apt-get autoremove -y',
|
|
65
|
-
'apt-get install -y ruby ruby-dev rubygems git-core libopenssl-ruby',
|
|
66
|
-
'gem sources -a http://gems.opscode.com',
|
|
67
|
-
'gem install chef ohai --no-rdoc --no-ri' ])
|
|
68
|
-
remote_instance.ssh(remote_instance.bootstrap_gems.collect { |g| "gem install #{g} --no-rdoc --no-ri" } )
|
|
82
|
+
|
|
83
|
+
def node_configure!(remote_instance)
|
|
84
|
+
# nothing in the superclass
|
|
69
85
|
end
|
|
86
|
+
|
|
87
|
+
def node_bootstrapped?(remote_instance, quiet=true)
|
|
88
|
+
# using which command instead of calling gem directly. On
|
|
89
|
+
# ubuntu, calling a command from package not installed
|
|
90
|
+
# 'helpfully' prints message, which result confuses detection
|
|
91
|
+
#
|
|
92
|
+
cmd = "which %s" % BOOTSTRAP_BINS.join(' ') +
|
|
93
|
+
" && dpkg -l %s " % BOOTSTRAP_PACKAGES.join(' ') +
|
|
94
|
+
BOOTSTRAP_GEMS.map{ |gem|
|
|
95
|
+
"&& gem search '^#{gem}$' | grep -v GEMS | wc -l | grep -q 1"
|
|
96
|
+
}.join(' ') +
|
|
97
|
+
BOOTSTRAP_DIRS.map{ |dir|
|
|
98
|
+
"&& [[ -d #{dir} ]] "
|
|
99
|
+
}.join(' ') +
|
|
100
|
+
(quiet ? " >/dev/null " : "" ) +
|
|
101
|
+
" && echo OK || echo MISSING"
|
|
102
|
+
|
|
103
|
+
r = remote_instance.ssh(cmd, :do_sudo => false )
|
|
104
|
+
r.lines.to_a.last.chomp == "OK"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def node_bootstrap!(remote_instance, force=false)
|
|
108
|
+
return if !force && node_bootstrapped?(remote_instance)
|
|
109
|
+
|
|
110
|
+
# TODO: this should not be hardcoded (like in node_run)
|
|
111
|
+
deb_gem_bin='/var/lib/gems/1.8/bin'
|
|
112
|
+
gem_src='http://gems.opscode.com'
|
|
113
|
+
|
|
114
|
+
bootstrap_cmds =
|
|
115
|
+
[
|
|
116
|
+
'apt-get update',
|
|
117
|
+
'apt-get autoremove -y',
|
|
118
|
+
'apt-get install -y %s' % BOOTSTRAP_PACKAGES.join(' '),
|
|
119
|
+
"gem source -l | grep -q #{gem_src} || gem source -a #{gem_src} ",
|
|
120
|
+
'gem install %s --no-rdoc --no-ri' %
|
|
121
|
+
(BOOTSTRAP_GEMS + remote_instance.bootstrap_gems).join(' '),
|
|
122
|
+
"apt-get install -y %s" % BOOTSTRAP_PACKAGES.join(' '),
|
|
123
|
+
"[ -d #{deb_gem_bin} ] && ln -sf #{deb_gem_bin}/* /usr/local/bin",
|
|
124
|
+
"mkdir -p %s" % BOOTSTRAP_DIRS.join(' ')
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
remote_instance.ssh(bootstrap_cmds)
|
|
128
|
+
end
|
|
129
|
+
|
|
70
130
|
private
|
|
131
|
+
|
|
132
|
+
def chef_cmd
|
|
133
|
+
return <<-CMD
|
|
134
|
+
PATH="$PATH:$GEM_BIN" #{chef_bin} -j /etc/chef/dna.json -c /etc/chef/client.rb -d -i 1800 -s 20
|
|
135
|
+
CMD
|
|
136
|
+
end
|
|
71
137
|
|
|
72
138
|
def _recipes
|
|
73
139
|
@_recipes ||= []
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
require 'uri' # for URI.parse in write_bootstrap_files
|
|
2
|
+
|
|
1
3
|
module PoolParty
|
|
2
4
|
# Chef class bootstrapping chef-client.
|
|
3
5
|
class ChefClient < Chef
|
|
4
|
-
dsl_methods :server_url,:validation_token
|
|
5
|
-
|
|
6
|
+
dsl_methods :server_url,:validation_token, :validation_key
|
|
7
|
+
|
|
8
|
+
# When init_style.nil?, old behavior is used (just run the client).
|
|
9
|
+
# If init_style is specified, bootstrap::client cookbook is executed
|
|
10
|
+
# To this init style.
|
|
11
|
+
dsl_methods :init_style
|
|
12
|
+
|
|
6
13
|
def openid_url(url=nil)
|
|
7
14
|
if url.nil?
|
|
8
15
|
return @openid_url||= (u=URI.parse(server_url)
|
|
@@ -18,27 +25,48 @@ module PoolParty
|
|
|
18
25
|
@_roles=roles
|
|
19
26
|
end
|
|
20
27
|
|
|
21
|
-
def compile!
|
|
22
|
-
build_tmp_dir
|
|
23
|
-
end
|
|
24
|
-
|
|
25
28
|
private
|
|
26
29
|
def after_initialized
|
|
27
30
|
raise PoolPartyError.create("ChefArgumentMissing", "server_url must be specified!") unless server_url
|
|
28
31
|
end
|
|
32
|
+
def chef_bin
|
|
33
|
+
"chef-client"
|
|
34
|
+
end
|
|
35
|
+
|
|
29
36
|
def chef_cmd
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
# without init_style, let parent class start chef-client
|
|
38
|
+
return super unless init_style
|
|
39
|
+
|
|
40
|
+
'invoke-rc.d chef-client start'
|
|
33
41
|
end
|
|
42
|
+
|
|
43
|
+
def node_configure!(remote_instance)
|
|
44
|
+
super
|
|
45
|
+
cmds =
|
|
46
|
+
[ 'PATH="$PATH:$GEM_BIN" chef-solo -j /tmp/chef/chef.json -c /tmp/chef/solo.rb',
|
|
47
|
+
'invoke-rc.d chef-client stop',
|
|
48
|
+
'PATH="$PATH:$GEM_BIN" chef-client -j /etc/chef/dna.json -c /etc/chef/client.rb',
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
remote_instance.ssh cmds
|
|
52
|
+
end
|
|
53
|
+
|
|
34
54
|
# The NEW actual chef resolver.
|
|
35
55
|
def build_tmp_dir
|
|
36
56
|
base_directory = tmp_path/"etc"/"chef"
|
|
37
57
|
FileUtils.rm_rf base_directory
|
|
38
58
|
FileUtils.mkdir_p base_directory
|
|
59
|
+
FileUtils.cp validation_key, base_directory if validation_key
|
|
39
60
|
puts "Creating the dna.json"
|
|
40
61
|
attributes.to_dna [], base_directory/"dna.json", {:run_list => roles.map{|r| "role[#{r}]"} + _recipes.map{|r| "recipe[#{r}]"}}.merge(attributes.init_opts)
|
|
41
|
-
|
|
62
|
+
unless init_style then # original style init
|
|
63
|
+
write_client_dot_rb
|
|
64
|
+
else
|
|
65
|
+
bootstrap_tmp_dir = tmp_path/"tmp/chef"
|
|
66
|
+
FileUtils.rm_rf bootstrap_tmp_dir
|
|
67
|
+
FileUtils.mkdir_p bootstrap_tmp_dir
|
|
68
|
+
write_bootstrap_files bootstrap_tmp_dir/"solo.rb", bootstrap_tmp_dir/"chef.json"
|
|
69
|
+
end
|
|
42
70
|
end
|
|
43
71
|
|
|
44
72
|
def write_client_dot_rb(to=tmp_path/"etc"/"chef"/"client.rb")
|
|
@@ -51,13 +79,43 @@ pid_file "/var/run/chef/client.pid"
|
|
|
51
79
|
Chef::Log::Formatter.show_time = true
|
|
52
80
|
openid_url "#{openid_url}"
|
|
53
81
|
EOE
|
|
54
|
-
%w(
|
|
82
|
+
%w(chef_server_url).each{|url|
|
|
55
83
|
content+="#{url} \"#{server_url}\"\n"
|
|
56
84
|
}
|
|
57
85
|
content+="validation_token \"#{validation_token}\"\n" if validation_token
|
|
86
|
+
content+="validation_key \"/etc/chef/#{File.basename validation_key}\"\n" if validation_key
|
|
58
87
|
File.open(to, "w") do |f|
|
|
59
88
|
f << content
|
|
60
89
|
end
|
|
61
90
|
end
|
|
91
|
+
|
|
92
|
+
def write_bootstrap_files(solo_rb, chef_json)
|
|
93
|
+
uri=URI.parse(server_url)
|
|
94
|
+
# this maybe reduntant, URL should have a port in there
|
|
95
|
+
uri.port=4000 if uri.port == 80 # default port for chef
|
|
96
|
+
|
|
97
|
+
contents_solo_rb = <<-EOE
|
|
98
|
+
file_cache_path "/tmp/chef-solo"
|
|
99
|
+
cookbook_path "/tmp/chef-solo/cookbooks"
|
|
100
|
+
recipe_url "http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz"
|
|
101
|
+
EOE
|
|
102
|
+
File.open(solo_rb, "w") do |f| f << contents_solo_rb end
|
|
103
|
+
|
|
104
|
+
bootstrap_json =
|
|
105
|
+
{
|
|
106
|
+
:bootstrap => {
|
|
107
|
+
:chef => {
|
|
108
|
+
:url_type => uri.scheme,
|
|
109
|
+
:init_style => init_style,
|
|
110
|
+
:path => "/srv/chef",
|
|
111
|
+
:serve_path => "/srv/chef",
|
|
112
|
+
:server_fqdn => uri.host,
|
|
113
|
+
:server_port => uri.port,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
:run_list => [ 'recipe[bootstrap::client]' ],
|
|
117
|
+
}
|
|
118
|
+
ChefAttribute.new(bootstrap_json).to_dna([], chef_json)
|
|
119
|
+
end
|
|
62
120
|
end
|
|
63
121
|
end
|
data/lib/poolparty/chef_solo.rb
CHANGED
|
@@ -3,16 +3,12 @@ require "fileutils"
|
|
|
3
3
|
module PoolParty
|
|
4
4
|
class ChefSolo < Chef
|
|
5
5
|
dsl_methods :repo
|
|
6
|
-
def compile!
|
|
7
|
-
build_tmp_dir
|
|
8
|
-
end
|
|
9
6
|
|
|
10
7
|
private
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
PATH="$PATH:$GEM_BIN" chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb
|
|
14
|
-
CMD
|
|
8
|
+
def chef_bin
|
|
9
|
+
"chef-solo"
|
|
15
10
|
end
|
|
11
|
+
|
|
16
12
|
# The NEW actual chef resolver.
|
|
17
13
|
def build_tmp_dir
|
|
18
14
|
base_directory = tmp_path/"etc"/"chef"
|
data/lib/poolparty.rb
CHANGED
|
@@ -20,6 +20,7 @@ module PoolParty
|
|
|
20
20
|
return @version if @version
|
|
21
21
|
config = YAML.load(File.read(File.expand_path("#{File.dirname(__FILE__)}/../VERSION.yml")))
|
|
22
22
|
@version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
|
23
|
+
@version += "-" + config[:build] if config[:build]
|
|
23
24
|
end
|
|
24
25
|
def self.lib_dir
|
|
25
26
|
File.join(File.dirname(__FILE__), "..")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
+
MIIEogIBAAKCAQEAywLYTlQ+keNiZI2FeBik6q34xStF3fF2+XPk3e21B0YQfbQI
|
|
3
|
+
xYJG8gbSro90Tu1hnEBZfYm+AC8HXsR9Kx9LpfTSa3aGFRREwdsi8xuaoeHWNxOh
|
|
4
|
+
MykU4UcxahT0Ft5+738kLmtVhw8bjjkqcpxCSgrpcJbad2B2ft1KBE02kiU2y7yS
|
|
5
|
+
92sUSWBzVkkJTmiWBDvn5pT9y6IpVCKseWbumGQ6nozEfXe4ihUsKAH42XPxSXMX
|
|
6
|
+
Xe64JuONQlxZPrqyF7L/lt6ZeyKQ7yXVcxr6P4W3rPqlBhq5yXNI3vV67KUNCh+w
|
|
7
|
+
HH6RLagaguS0VTdBYwo3dvkmuL6TJqnzPzrv1wIBIwKCAQBczhm9aFceHs3k0vsv
|
|
8
|
+
ljzDDbONVZxIM96d69ZW0xDtYdunLbrd8mmTNlGu4n5P930UOqyRKQZme+YcsZhO
|
|
9
|
+
OjE17ELvTCAJot2acs4l/f2L1PQ2b1+iW+xJuiU3zxB/e6e98PqY4Jwge+9W9Y+/
|
|
10
|
+
XWAh2RpCGRNpxbKDI1UJR95usRxhxlmY0RmUtpDjc3qEOPRgj7E2iC4fFVdvYzKt
|
|
11
|
+
FBkGR6Gv2/jqm+c/TmRCFnyaWJXC8W6LkkACjUc6IKUOBSbs6l+3DH0PBOr+XbGv
|
|
12
|
+
peExAfYCTfvGy/NNPpzP0JJUJ92sWaZUPUTf8McSsgrTTRBfklsJuf9Hje/8abcr
|
|
13
|
+
AheLAoGBAPGX3CDMU68BTgO8bOvGhFHQSu9AypIhEh0PrE1CYsEvYrIRg9h23fuz
|
|
14
|
+
1nz7Z6kIYTNMywxfphEL65CTiJ5eSJV+UGMFAKYziCwH7MDD4Wc6cPLrGmA0eYDz
|
|
15
|
+
QMUQJwqfuXKq/dMw2VB6qGbNmbERWmq3wteF/afyTatd6poV4UcXAoGBANcd/o4s
|
|
16
|
+
zf1SwxKoT4GGp62gtqT+gIbGkV0AzWBcaDarRNbcV7uFZLL7wzPcCR8/cPZiN+ks
|
|
17
|
+
+LsVYvDfrFHRxtdzIesxcqG2v6LazB/+/rZp4Hqc1a4OwxSdOYzINjA01GV2HcET
|
|
18
|
+
XzoJIQA8ZYuVpELaNzjLtKBZ6mrQmBh7RRVBAoGBAJ7C4RzeCxs7XycGyzvaObIb
|
|
19
|
+
Ke2uO/mgtCG516B8FQKbe18S0vv2V1xC+qnnCZr24MnworBcHKwdxq925L/Xjsij
|
|
20
|
+
dqd4UOI/Hvhc+qqPWZubbsuEjazvSIfwTyJps0F+55R+/pIYyVIkt86HG9rCQrso
|
|
21
|
+
TNbFw/IFoMER1K5mJlNJAoGAT+aRv8d/tdzpXrOLPrz8c7C43jKkxFhh4LcnthOx
|
|
22
|
+
refXvYUKpLyEfP5tE0MZVL/K3yvLn8A/IOqvuI2Xxp5fzF32p9CJqceJAfl/BJHp
|
|
23
|
+
lDX0SsyJ4ZB0WB0kARcqEee8mrbX2f/hipWtK/ktB/XAqx3Z/ycXND6nhsKBorFx
|
|
24
|
+
bksCgYEAtPns7oc98wmF8j37ELikMFJOvQgccbGTzcJ1RVzji95HfN4p3kA6emo/
|
|
25
|
+
hRyP8XNedEI/CD6MmthKKymw5Ck1I51nwDW4+zTEDAN14nh4T9p6Jqe7lSENqLaY
|
|
26
|
+
A5jkgXV8e0YqKkjLNec5hAzoEY09KryQdz81KXeHvbEUfIiItTk=
|
|
27
|
+
-----END RSA PRIVATE KEY-----
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-----BEGIN RSA PUBLIC KEY-----
|
|
2
|
+
MIIBCAKCAQEAywLYTlQ+keNiZI2FeBik6q34xStF3fF2+XPk3e21B0YQfbQIxYJG
|
|
3
|
+
8gbSro90Tu1hnEBZfYm+AC8HXsR9Kx9LpfTSa3aGFRREwdsi8xuaoeHWNxOhMykU
|
|
4
|
+
4UcxahT0Ft5+738kLmtVhw8bjjkqcpxCSgrpcJbad2B2ft1KBE02kiU2y7yS92sU
|
|
5
|
+
SWBzVkkJTmiWBDvn5pT9y6IpVCKseWbumGQ6nozEfXe4ihUsKAH42XPxSXMXXe64
|
|
6
|
+
JuONQlxZPrqyF7L/lt6ZeyKQ7yXVcxr6P4W3rPqlBhq5yXNI3vV67KUNCh+wHH6R
|
|
7
|
+
LagaguS0VTdBYwo3dvkmuL6TJqnzPzrv1wIBIw==
|
|
8
|
+
-----END RSA PUBLIC KEY-----
|
|
@@ -6,6 +6,7 @@ class KeypairTest < Test::Unit::TestCase
|
|
|
6
6
|
context "Base" do
|
|
7
7
|
setup do
|
|
8
8
|
@keypair = Keypair.new(fixtures_dir/"keys"/"test_key")
|
|
9
|
+
@keypair_pem = Keypair.new(fixtures_dir/"keys"/"pem_key")
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
should "set the file given as the file for the keypair" do
|
|
@@ -13,6 +14,25 @@ class KeypairTest < Test::Unit::TestCase
|
|
|
13
14
|
assert_equal @keypair.full_filepath, File.expand_path(fixtures_dir/"keys"/"test_key")
|
|
14
15
|
assert_match @keypair.to_s, File.expand_path(fixtures_dir/"keys"/"test_key")
|
|
15
16
|
end
|
|
17
|
+
|
|
18
|
+
should "find the suffixed file given without pem suffix" do
|
|
19
|
+
assert_equal @keypair_pem.filepath, fixtures_dir/"keys"/"pem_key"
|
|
20
|
+
assert_equal @keypair_pem.full_filepath, File.expand_path(fixtures_dir/"keys"/"pem_key.pem")
|
|
21
|
+
assert_match @keypair_pem.to_s, File.expand_path(fixtures_dir/"keys"/"pem_key")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
should "find the suffixed file given without pem suffix or dir" do
|
|
25
|
+
basename = File.basename(@keypair_pem.full_filepath)
|
|
26
|
+
basename_no_suffix = File.basename(basename, '.pem')
|
|
27
|
+
|
|
28
|
+
search_dirs = [File.dirname(@keypair_pem.full_filepath)]
|
|
29
|
+
|
|
30
|
+
keypair = Keypair.new(basename, search_dirs)
|
|
31
|
+
keypair_no_suffix = Keypair.new(basename_no_suffix, search_dirs)
|
|
32
|
+
|
|
33
|
+
assert_equal keypair.full_filepath, @keypair_pem.full_filepath
|
|
34
|
+
assert_equal keypair_no_suffix.full_filepath, @keypair_pem.full_filepath
|
|
35
|
+
end
|
|
16
36
|
|
|
17
37
|
should "have the content of the file available" do
|
|
18
38
|
assert_equal @keypair.content, open(fixtures_dir/"keys"/"test_key").read
|
|
@@ -37,4 +57,4 @@ class KeypairTest < Test::Unit::TestCase
|
|
|
37
57
|
end
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
|
-
end
|
|
60
|
+
end
|
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.6.
|
|
4
|
+
version: 1.6.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ari Lerner
|
|
@@ -291,6 +291,8 @@ files:
|
|
|
291
291
|
- test/fixtures/ec2/ec2-terminate-instances_response_body.xml
|
|
292
292
|
- test/fixtures/ec2/elb-describe-load-balancers.xml
|
|
293
293
|
- test/fixtures/ec2/rds-describe-db-instances-empty_response_body.xml
|
|
294
|
+
- test/fixtures/keys/pem_key.pem
|
|
295
|
+
- test/fixtures/keys/pem_pub_key.pem
|
|
294
296
|
- test/fixtures/keys/test_key
|
|
295
297
|
- test/fixtures/keys/test_pub_key
|
|
296
298
|
- test/fixtures/resources/fake_plugin.rb
|