poolparty 1.6.8 → 1.6.9
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/Rakefile +12 -2
- data/VERSION.yml +2 -1
- data/bin/cloud +4 -1
- data/bin/cloud-run +2 -2
- data/bin/cloud-show +11 -10
- data/lib/cloud_providers/connections.rb +4 -2
- data/lib/cloud_providers/ec2/ec2.rb +58 -39
- data/lib/cloud_providers/ec2/ec2_instance.rb +50 -40
- data/lib/cloud_providers/ec2/helpers/authorize.rb +8 -3
- data/lib/cloud_providers/ec2/helpers/elastic_auto_scaler.rb +7 -4
- data/lib/cloud_providers/ec2/helpers/revoke.rb +5 -5
- data/lib/cloud_providers/ec2/helpers/security_group.rb +29 -32
- data/lib/cloud_providers/remote_instance.rb.orig +162 -0
- data/lib/core/object.rb +16 -1
- data/lib/keypair.rb +21 -21
- data/lib/poolparty/chef.rb +71 -6
- data/lib/poolparty/chef_client.rb +6 -2
- data/lib/poolparty/chef_solo.rb +18 -2
- data/lib/poolparty/cloud.rb +13 -0
- data/lib/poolparty/cloud.rb.orig +432 -0
- data/lib/poolparty/pool.rb +36 -2
- metadata +7 -12
|
@@ -12,12 +12,17 @@ module CloudProviders
|
|
|
12
12
|
options =
|
|
13
13
|
if group_name
|
|
14
14
|
puts "Authorizing #{name} for group named: #{group_name} of owner id: #{owner_id}"
|
|
15
|
-
{:
|
|
15
|
+
{:group_name => name, :source_security_group_name=> group_name, :source_security_group_owner_id => owner_id}
|
|
16
16
|
else
|
|
17
17
|
puts "Authorizing: #{name} for #{protocol} to #{from_port}:#{to_port} #{network}"
|
|
18
18
|
to_hash
|
|
19
19
|
end
|
|
20
|
-
|
|
20
|
+
begin
|
|
21
|
+
ec2.authorize_security_group_ingress(options)
|
|
22
|
+
rescue AWS::InvalidPermissionDuplicate => e
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def to_hash
|
|
@@ -35,4 +40,4 @@ module CloudProviders
|
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
end
|
|
38
|
-
end
|
|
43
|
+
end
|
|
@@ -321,13 +321,14 @@ module CloudProviders
|
|
|
321
321
|
:measure => :cpu,
|
|
322
322
|
:period => 60,
|
|
323
323
|
:statistic => :average,
|
|
324
|
-
:unit => "
|
|
324
|
+
:unit => "Percent",
|
|
325
325
|
:lower_threshold => 20,
|
|
326
326
|
:upper_threshold => 60,
|
|
327
327
|
:trigger_name => "CpuTrigger",
|
|
328
328
|
:lower_breach_scale_increment => -1,
|
|
329
329
|
:upper_breach_scale_increment => 1,
|
|
330
|
-
:breach_duration => 120
|
|
330
|
+
:breach_duration => 120,
|
|
331
|
+
:namespace => 'AWS/EC2'
|
|
331
332
|
)
|
|
332
333
|
|
|
333
334
|
def measure_names
|
|
@@ -392,7 +393,8 @@ module CloudProviders
|
|
|
392
393
|
:breach_duration => trigger["BreachDuration"],
|
|
393
394
|
:dimensions => trigger["Dimensions"],
|
|
394
395
|
:unit => trigger["Unit"],
|
|
395
|
-
:autoscaling_group_name => trigger["AutoScalingGroupName"]
|
|
396
|
+
:autoscaling_group_name => trigger["AutoScalingGroupName"],
|
|
397
|
+
:namespace => trigger['Namespace']
|
|
396
398
|
}
|
|
397
399
|
end
|
|
398
400
|
rescue Exception => e
|
|
@@ -412,7 +414,8 @@ module CloudProviders
|
|
|
412
414
|
:lower_threshold => "#{lower_threshold}",
|
|
413
415
|
:lower_breach_scale_increment => "#{lower_breach_scale_increment}",
|
|
414
416
|
:upper_threshold => "#{upper_threshold}",
|
|
415
|
-
:upper_breach_scale_increment => "#{upper_breach_scale_increment}"
|
|
417
|
+
:upper_breach_scale_increment => "#{upper_breach_scale_increment}",
|
|
418
|
+
:namespace => namespace
|
|
416
419
|
)
|
|
417
420
|
end
|
|
418
421
|
|
|
@@ -7,8 +7,8 @@ module CloudProviders
|
|
|
7
7
|
:to_port => "22",
|
|
8
8
|
:cidr_ip => "0.0.0.0/0"})
|
|
9
9
|
def run
|
|
10
|
-
puts "Revoking: #{
|
|
11
|
-
options = { :group_name =>
|
|
10
|
+
puts "Revoking: #{name} for #{protocol} to #{from_port}:#{to_port} #{network}"
|
|
11
|
+
options = { :group_name => name,
|
|
12
12
|
:ip_protocol => protocol,
|
|
13
13
|
:from_port => from_port,
|
|
14
14
|
:to_port => to_port,
|
|
@@ -16,9 +16,9 @@ module CloudProviders
|
|
|
16
16
|
|
|
17
17
|
ec2.revoke_security_group_ingress(options) rescue nil
|
|
18
18
|
end
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
alias :network :cidr_ip
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
end
|
|
24
|
+
end
|
|
@@ -1,57 +1,54 @@
|
|
|
1
1
|
module CloudProviders
|
|
2
2
|
class SecurityGroup < Ec2Helper
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
def run
|
|
5
5
|
if should_create_security_group?
|
|
6
6
|
create_security_group!
|
|
7
7
|
end
|
|
8
|
-
current_security_groups = security_groups.map {|a|
|
|
8
|
+
current_security_groups = security_groups.map {|a|
|
|
9
|
+
# Example:
|
|
10
|
+
# [{ :ip_permissions=>[
|
|
11
|
+
# {:ip_ranges=>[{:cidr_ip=>"0.0.0.0/0"}], :from_port=>"22", :protocol=>"tcp", :to_port=>"22"},
|
|
12
|
+
# {:ip_ranges=>[{:cidr_ip=>"0.0.0.0/0"}], :from_port=>"80", :protocol=>"tcp", :to_port=>"80"} ],
|
|
13
|
+
# :description=>"PoolParty generated security group: clyde-chefclient", :name=>"clyde-chefclient"}]
|
|
14
|
+
#
|
|
9
15
|
a[:ip_permissions].map do |perm|
|
|
10
16
|
if perm[:group_name]
|
|
11
17
|
{
|
|
12
18
|
:group_name => perm[:group_name]
|
|
13
19
|
}
|
|
14
20
|
else
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
:group_name => a[:name],
|
|
19
|
-
:from_port => perm[:from_port],
|
|
20
|
-
:to_port => perm[:to_port],
|
|
21
|
-
:cidr_ip => range,
|
|
22
|
-
:ip_protocol => perm[:protocol]
|
|
23
|
-
}.flatten
|
|
24
|
-
end.flatten
|
|
25
|
-
else
|
|
21
|
+
(perm[:ip_ranges] || ["0.0.0.0/0"]).map do |range|
|
|
22
|
+
range = range[:cidr_ip] if range.is_a?(Hash)
|
|
26
23
|
{
|
|
27
|
-
:group_name
|
|
28
|
-
:from_port
|
|
29
|
-
:to_port
|
|
30
|
-
:cidr_ip
|
|
24
|
+
:group_name => a[:name],
|
|
25
|
+
:from_port => perm[:from_port].to_i,
|
|
26
|
+
:to_port => perm[:to_port].to_i,
|
|
27
|
+
:cidr_ip => range,
|
|
31
28
|
:ip_protocol => perm[:protocol]
|
|
32
29
|
}
|
|
33
|
-
end
|
|
30
|
+
end.flatten
|
|
34
31
|
end
|
|
35
32
|
end.flatten
|
|
36
33
|
}.flatten
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
|
|
35
|
+
authorizes_requested = authorizes.select{|a| a.name == name }
|
|
36
|
+
authorizes_requested_hashes = authorizes_requested.map{|a| a.to_hash}
|
|
37
|
+
authorizes_needed = []
|
|
38
|
+
|
|
39
|
+
# take each requested authorization. If it doesn't exist in the current_security_groups, we need to add it.
|
|
40
|
+
authorizes_requested.each do |a|
|
|
41
|
+
authorizes_needed << a unless current_security_groups.include?(a.to_hash)
|
|
43
42
|
end
|
|
44
|
-
|
|
45
|
-
defined_security_group_hashes = authorizes.map {|a| a.to_hash}
|
|
46
|
-
|
|
43
|
+
# conversely, every current_security_groups authorization that isn't in the authorizes_requested list must be revoked
|
|
47
44
|
current_security_groups.each do |hsh|
|
|
48
|
-
unless
|
|
45
|
+
unless authorizes_requested_hashes.include?(hsh)
|
|
49
46
|
revoke(hsh.merge(:protocol => hsh[:ip_protocol]))
|
|
50
47
|
end
|
|
51
48
|
end
|
|
52
|
-
|
|
49
|
+
|
|
53
50
|
revokes.each {|r| r.run }
|
|
54
|
-
|
|
51
|
+
authorizes_needed.each {|a| a.run}
|
|
55
52
|
end
|
|
56
53
|
def authorize(o={}, &block)
|
|
57
54
|
authorizes << Authorize.new("#{name}", o.merge(:parent => parent, :cloud => cloud), &block)
|
|
@@ -82,7 +79,7 @@ module CloudProviders
|
|
|
82
79
|
:to_port => i["toPort"],
|
|
83
80
|
:ip_ranges => ip_ranges["item"].map do |ip|
|
|
84
81
|
{
|
|
85
|
-
:
|
|
82
|
+
:cidr_ip => ip["cidrIp"]
|
|
86
83
|
}
|
|
87
84
|
end
|
|
88
85
|
}
|
|
@@ -101,4 +98,4 @@ module CloudProviders
|
|
|
101
98
|
end
|
|
102
99
|
end
|
|
103
100
|
|
|
104
|
-
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
=begin rdoc
|
|
2
|
+
Remote instances
|
|
3
|
+
=end
|
|
4
|
+
module CloudProviders
|
|
5
|
+
class RemoteInstance
|
|
6
|
+
include Dslify, Connections
|
|
7
|
+
|
|
8
|
+
attr_reader :name, :init_opts, :raw_response
|
|
9
|
+
attr_accessor :cloud_provider
|
|
10
|
+
|
|
11
|
+
default_options(
|
|
12
|
+
:instance_id => nil,
|
|
13
|
+
:image_id => nil,
|
|
14
|
+
:status => nil
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
def initialize(init_opts={}, &block)
|
|
18
|
+
@init_opts = init_opts
|
|
19
|
+
set_vars_from_options(init_opts)
|
|
20
|
+
instance_eval &block if block
|
|
21
|
+
after_initialized
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def keypair(n=nil)
|
|
25
|
+
@keypair ||= n.nil? ? nil : Keypair.new(n)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def after_initialized
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def accessible?
|
|
32
|
+
ping_port(public_ip, 22, 40)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def rsync_dir(dir)
|
|
36
|
+
rsync :source => dir/"*", :destination => "/"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def chef_bootstrapped?
|
|
40
|
+
# do_sudo is false cause we want to capture the return code of the call
|
|
41
|
+
@chef_bootstrapped ||= cloud.chef.node_bootsrapped?(self)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def bootstrap_chef!
|
|
45
|
+
<<<<<<< HEAD:lib/cloud_providers/remote_instance.rb
|
|
46
|
+
unless chef_bootstrapped?
|
|
47
|
+
ssh([
|
|
48
|
+
'apt-get update',
|
|
49
|
+
'apt-get autoremove -y',
|
|
50
|
+
'apt-get install -y ruby ruby-dev rubygems git-core libopenssl-ruby',
|
|
51
|
+
'gem sources -a http://gems.opscode.com',
|
|
52
|
+
'gem install chef ohai --no-rdoc --no-ri' ])
|
|
53
|
+
end
|
|
54
|
+
if bootstrap_gems.size > 0
|
|
55
|
+
ssh(bootstrap_gems.collect { |gem| "gem install #{gem} --no-rdoc --no-ri" } )
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def run_chef!
|
|
60
|
+
if ENV["CHEF_DEBUG"]
|
|
61
|
+
debug = "-l debug"
|
|
62
|
+
else
|
|
63
|
+
debug = ""
|
|
64
|
+
end
|
|
65
|
+
chef_solo_cmd = <<-CMD
|
|
66
|
+
$GEM_BIN/chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb #{debug}
|
|
67
|
+
CMD
|
|
68
|
+
envhash = {
|
|
69
|
+
:GEM_BIN => %q%$(gem env | grep "EXECUTABLE DIRECTORY" | awk "{print \\$4}")%
|
|
70
|
+
}
|
|
71
|
+
ssh([chef_solo_cmd.strip.squeeze(' ')], :env => envhash )
|
|
72
|
+
=======
|
|
73
|
+
cloud.chef.node_bootstrap(self) unless chef_bootstrapped?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def run_chef!
|
|
77
|
+
cloud.chef.node_run!(self)
|
|
78
|
+
>>>>>>> 81a7e0df2d02545ff9b22572194a4f115f73906a:lib/cloud_providers/remote_instance.rb
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def run
|
|
82
|
+
warn "#{self.class} does not implement run. Something is wrong"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def default_keypair_path
|
|
86
|
+
self.class.default_keypair_path
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
## provide hash like methods to access and iterate over node attributes
|
|
90
|
+
def each
|
|
91
|
+
dsl_options.each{ |k,v| yield k,v }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def [](k)
|
|
95
|
+
if dsl_options.has_key? k
|
|
96
|
+
dsl_options[k]
|
|
97
|
+
else
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def []=(k,v)
|
|
103
|
+
dsl_options[k] = v
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def has_key?(key)
|
|
107
|
+
dsl_options.has_key?(key)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def keys
|
|
111
|
+
dsl_options.keys
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def values
|
|
115
|
+
dsl_options.values
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def to_hash
|
|
119
|
+
dsl_options
|
|
120
|
+
end
|
|
121
|
+
##end of hash like methods
|
|
122
|
+
|
|
123
|
+
# Is this instance running?
|
|
124
|
+
def running?
|
|
125
|
+
!(status =~ /running/).nil?
|
|
126
|
+
end
|
|
127
|
+
# Is this instance pending?
|
|
128
|
+
def pending?
|
|
129
|
+
!(status =~ /pending/).nil?
|
|
130
|
+
end
|
|
131
|
+
# Is this instance terminating?
|
|
132
|
+
def terminating?
|
|
133
|
+
!(status =~ /shutting/).nil?
|
|
134
|
+
end
|
|
135
|
+
# Has this instance been terminated?
|
|
136
|
+
def terminated?
|
|
137
|
+
!(status =~ /terminated/).nil?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# elapsed seconds since node launch time
|
|
141
|
+
def elapsed_runtime
|
|
142
|
+
Time.now - Time.parse(launch_time)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def ssh_available?
|
|
146
|
+
warn "Implemented in cloudprovider instance class. something is wrong"
|
|
147
|
+
end
|
|
148
|
+
# def to_s
|
|
149
|
+
# (cloud ? to_hash.merge(:cloud=>cloud.name) : to_hash)
|
|
150
|
+
# end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
def cloud
|
|
154
|
+
init_opts.has_key?(:cloud) ? init_opts[:cloud] : nil
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def cloud_provider
|
|
158
|
+
cloud.cloud_provider
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
end
|
data/lib/core/object.rb
CHANGED
|
@@ -13,6 +13,21 @@ class Object
|
|
|
13
13
|
puts line
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
# === Description
|
|
18
|
+
#
|
|
19
|
+
# Change +attr+ to +val+ within the scope of block
|
|
20
|
+
# and then sets it back again
|
|
21
|
+
#
|
|
22
|
+
def change_attr attr, val, &block
|
|
23
|
+
old_val = instance_variable_get attr
|
|
24
|
+
begin
|
|
25
|
+
instance_variable_set attr, val
|
|
26
|
+
yield
|
|
27
|
+
ensure
|
|
28
|
+
instance_variable_set attr, old_val
|
|
29
|
+
end
|
|
30
|
+
end
|
|
16
31
|
|
|
17
32
|
def progress_bar_until(msg=nil, &block)
|
|
18
33
|
print "#{msg}" if msg
|
|
@@ -30,4 +45,4 @@ class Object
|
|
|
30
45
|
end
|
|
31
46
|
|
|
32
47
|
|
|
33
|
-
end
|
|
48
|
+
end
|
data/lib/keypair.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
ssh key used to login to remote instances\
|
|
3
3
|
=end
|
|
4
4
|
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
|
|
|
@@ -12,37 +12,37 @@ class Keypair
|
|
|
12
12
|
attr_accessor :filepath
|
|
13
13
|
attr_reader :extra_paths, :opts
|
|
14
14
|
attr_reader :search_suffixes
|
|
15
|
-
|
|
16
|
-
# Create a new key that defaults to id_rsa as the name.
|
|
15
|
+
|
|
16
|
+
# Create a new key that defaults to id_rsa as the name.
|
|
17
17
|
def initialize(fpath, extra_paths=[], opts={})
|
|
18
18
|
@filepath = fpath
|
|
19
19
|
@opts = opts
|
|
20
20
|
@extra_paths = extra_paths.map {|a| File.expand_path(a) }
|
|
21
21
|
@search_suffixes = SEARCH_SUFFIXES
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# If the full_filepath is nil or false, then the key doesn't exist
|
|
25
25
|
def exists?
|
|
26
26
|
!! full_filepath
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
# Read the content of the key
|
|
30
30
|
def content
|
|
31
31
|
@content ||= exists? ? open(full_filepath).read : nil
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# Returns the full_filepath of the key. If a full filepath is passed, we just return the expanded filepath
|
|
35
35
|
# for the keypair, otherwise query where it is against known locations
|
|
36
36
|
def full_filepath
|
|
37
|
-
@full_filepath ||=
|
|
38
|
-
find_file_in_path_with_suffix(filepath, extra_paths,
|
|
37
|
+
@full_filepath ||=
|
|
38
|
+
find_file_in_path_with_suffix(filepath, extra_paths,
|
|
39
39
|
search_suffixes) || false
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
def to_s
|
|
43
43
|
basename
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
#TODO: gracefully handle the case when a passpharase is needed
|
|
47
47
|
# Generate a public key from the private key
|
|
48
48
|
# net/ssh already has this built-in from our extension.
|
|
@@ -54,21 +54,21 @@ class Keypair
|
|
|
54
54
|
@public_key_string
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
def public_key=(str)
|
|
59
59
|
@public_key_string = str
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
# Basename of the keypair
|
|
63
63
|
def basename
|
|
64
64
|
@basename ||= ::File.basename(filepath, ::File.extname(filepath))
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
# Just the filename of the keypair
|
|
68
68
|
def filename
|
|
69
69
|
@filename ||= ::File.basename(full_filepath) rescue filepath
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
# Support to add the enumerable each to keys
|
|
73
73
|
def each
|
|
74
74
|
yield full_filepath
|
|
@@ -80,19 +80,19 @@ class Keypair
|
|
|
80
80
|
def valid?
|
|
81
81
|
validations.each {|validation| self.send(validation.to_sym) }
|
|
82
82
|
end
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
private
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
# Validations
|
|
87
87
|
def validations
|
|
88
88
|
[:keypair_found?, :has_proper_permissions?]
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
# Check the proper permissions
|
|
92
92
|
def has_proper_permissions?
|
|
93
93
|
perm_truth = [:readable?, :writable?, :executable?].map {|meth| File.send(meth, full_filepath)} == [true, true, false]
|
|
94
94
|
raise StandardError.new("Your keypair #{full_filepath} has improper file permissions. Keypairs must be 0600 permission. Please chmod your keypair file and try again") unless perm_truth
|
|
95
|
-
end
|
|
95
|
+
end
|
|
96
96
|
def keypair_found?
|
|
97
97
|
if exists?
|
|
98
98
|
true
|
|
@@ -103,10 +103,10 @@ class Keypair
|
|
|
103
103
|
|
|
104
104
|
# try filename with suffix and without suffixes.
|
|
105
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=[],
|
|
106
|
+
def find_file_in_path_with_suffix(file, extra_paths, suffixes=[],
|
|
107
107
|
try_wo_suffix=true)
|
|
108
108
|
suffixes_to_try = suffixes.dup
|
|
109
|
-
suffixes_to_try.
|
|
109
|
+
suffixes_to_try.push '' if try_wo_suffix
|
|
110
110
|
|
|
111
111
|
suffixes_to_try.map {|s| file + s }.each do |suffixed|
|
|
112
112
|
fullpath = if File.file?(File.expand_path(suffixed))
|
|
@@ -119,5 +119,5 @@ class Keypair
|
|
|
119
119
|
|
|
120
120
|
nil
|
|
121
121
|
end
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
end
|