collins_shell 0.2.17 → 0.2.18
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/collins_shell.gemspec +2 -2
- data/lib/collins_shell/asset.rb +8 -3
- data/lib/collins_shell/console/commands/cat.rb +1 -0
- data/lib/collins_shell/thor.rb +10 -2
- data/lib/collins_shell/util.rb +55 -2
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.18
|
data/collins_shell.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "collins_shell"
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.18"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Blake Matheny"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-03-19"
|
13
13
|
s.description = "Provides basic CLI for interacting with Collins API"
|
14
14
|
s.email = "bmatheny@tumblr.com"
|
15
15
|
s.executables = ["collins-shell"]
|
data/lib/collins_shell/asset.rb
CHANGED
@@ -49,8 +49,8 @@ module CollinsShell
|
|
49
49
|
method_option :exec, :type => :string, :desc => 'Execute a command using the data from this asset. Use {{hostname}}, {{ipmi.password}}, etc for substitution'
|
50
50
|
method_option :header, :type => :boolean, :default => true, :desc => 'Display a tag header. Defaults to true'
|
51
51
|
method_option :logs, :type => :boolean, :default => false, :desc => 'Also display asset logs, only used with details (SLOW)'
|
52
|
-
method_option :size, :type => :numeric, :default => 50, :desc => 'Number of results to find. Defaults to 50'
|
53
52
|
method_option :tags, :type => :array, :desc => 'Tags to display of form: tag1 tag2 tag3. e.g. --tags=hostname tag backend_ip_address'
|
53
|
+
method_option :threads, :type => :numeric, :default => 1, :desc => 'Number of threads to use for --exec. Defaults to 1.'
|
54
54
|
method_option :url, :type => :boolean, :default => true, :desc => 'Display a URL along with tags or the default listing'
|
55
55
|
def find
|
56
56
|
client = get_collins_client
|
@@ -69,14 +69,15 @@ module CollinsShell
|
|
69
69
|
:detailed => !options.exec?
|
70
70
|
puts printer
|
71
71
|
end
|
72
|
-
asset_exec asset, options.exec, options.confirm
|
72
|
+
asset_exec asset, options.exec, options.confirm, options.threads
|
73
73
|
end
|
74
74
|
else
|
75
75
|
if not options.quiet then
|
76
76
|
print_find_results assets, options.tags, :header => options.header, :url => options.url
|
77
77
|
end
|
78
|
-
assets.each {|asset| asset_exec(asset, options.exec, options.confirm)}
|
78
|
+
assets.each {|asset| asset_exec(asset, options.exec, options.confirm, options.threads)}
|
79
79
|
end
|
80
|
+
finalize_exec
|
80
81
|
end
|
81
82
|
|
82
83
|
desc 'find_similar TAG', 'get similar unallocated assets for a gven asset'
|
@@ -136,6 +137,7 @@ module CollinsShell
|
|
136
137
|
batch_selector_operation Hash[
|
137
138
|
:remote => options.remote,
|
138
139
|
:operation => "set_attribute",
|
140
|
+
:size => options["size"],
|
139
141
|
:success_message => proc {|asset| "Set attribute on #{asset.tag}"},
|
140
142
|
:error_message => proc{|asset| "Setting attribute on #{asset.tag}"},
|
141
143
|
:confirmation_message => proc do |assets|
|
@@ -172,6 +174,7 @@ module CollinsShell
|
|
172
174
|
batch_selector_operation Hash[
|
173
175
|
:remote => options.remote,
|
174
176
|
:operation => "set_attributes",
|
177
|
+
:size => options["size"],
|
175
178
|
:success_message => proc {|asset| "Set attributes on #{asset.tag}"},
|
176
179
|
:error_message => proc{|asset| "Setting attributes on #{asset.tag}"},
|
177
180
|
:confirmation_message => proc do |assets|
|
@@ -190,6 +193,7 @@ module CollinsShell
|
|
190
193
|
batch_selector_operation Hash[
|
191
194
|
:remote => options.remote,
|
192
195
|
:operation => "delete_attribute",
|
196
|
+
:size => options["size"],
|
193
197
|
:success_message => proc {|asset| "Delete attribute on #{asset.tag}"},
|
194
198
|
:error_message => proc{|asset| "Delete attribute on #{asset.tag}"},
|
195
199
|
:confirmation_message => proc do |assets|
|
@@ -217,6 +221,7 @@ module CollinsShell
|
|
217
221
|
batch_selector_operation Hash[
|
218
222
|
:remote => options.remote,
|
219
223
|
:operation => "set_status",
|
224
|
+
:size => options["size"],
|
220
225
|
:success_message => proc {|asset| "Set status to #{status} on #{asset.tag}"},
|
221
226
|
:error_message => proc{|asset| "Setting status on #{asset.tag}"},
|
222
227
|
:confirmation_message => proc do |assets|
|
data/lib/collins_shell/thor.rb
CHANGED
@@ -48,6 +48,7 @@ module CollinsShell
|
|
48
48
|
def use_selector_option required = false
|
49
49
|
method_option :selector, :type => :hash, :required => required, :desc => 'Selector to query collins. Takes the form of --selector=key1:val1 key2:val2 etc'
|
50
50
|
method_option :remote, :type => :boolean, :default => false, :desc => 'Search all collins instances, including remote ones'
|
51
|
+
method_option :size, :type => :numeric, :default => 50, :desc => 'Number of results to find. Defaults to 50'
|
51
52
|
end
|
52
53
|
|
53
54
|
def selector_or_tag
|
@@ -61,9 +62,16 @@ module CollinsShell
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def require_yes message, color = nil, should_exit = true
|
65
|
+
def appropriate_answer?(a); na = a.to_s.downcase.strip; na == 'yes' || na == 'no'; end
|
64
66
|
highline = HighLine.new
|
65
67
|
colored_message = set_color(message, color)
|
66
|
-
answer =
|
68
|
+
answer = nil
|
69
|
+
while !appropriate_answer?(answer) do
|
70
|
+
unless answer.nil? then
|
71
|
+
say_status "error", "Please type 'yes' or 'no'.", :red
|
72
|
+
end
|
73
|
+
answer = ask(colored_message)
|
74
|
+
end
|
67
75
|
if answer.downcase.strip !~ /^yes$/ then
|
68
76
|
if should_exit then
|
69
77
|
exit(0)
|
@@ -84,7 +92,7 @@ module CollinsShell
|
|
84
92
|
require_non_empty(success_message, "success_message not set")
|
85
93
|
require_non_empty(error_message, "error_message not set")
|
86
94
|
require_non_empty(operation, "operation not set")
|
87
|
-
selector = get_selector selector_or_tag, [],
|
95
|
+
selector = get_selector selector_or_tag, [], options[:size], options[:remote]
|
88
96
|
call_collins get_collins_client, operation do |client|
|
89
97
|
assets = client.find selector
|
90
98
|
if assets.length > 1 then
|
data/lib/collins_shell/util.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'collins_shell/monkeypatch'
|
2
2
|
require 'collins_shell/util/asset_stache'
|
3
|
+
require 'open3'
|
3
4
|
|
4
5
|
module CollinsShell
|
5
6
|
module Util
|
@@ -50,13 +51,65 @@ module CollinsShell
|
|
50
51
|
selector
|
51
52
|
end
|
52
53
|
|
53
|
-
def asset_exec asset, execs, confirm = true
|
54
|
+
def asset_exec asset, execs, confirm = true, threads = 1
|
54
55
|
return unless execs
|
55
56
|
mustache = CollinsShell::Util::AssetStache.new asset
|
56
57
|
rendered = mustache.render "/bin/bash -c '#{execs}'"
|
57
58
|
say_status("exec", rendered, :red)
|
58
59
|
require_yes("Running on #{asset.tag}. ARE YOU SURE?", :red) if confirm
|
59
|
-
|
60
|
+
if threads < 2 then
|
61
|
+
system(rendered)
|
62
|
+
else
|
63
|
+
run_command_in_thread(rendered, threads)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Should be called after asset_exec
|
68
|
+
def finalize_exec
|
69
|
+
thread_mgr.threads.each(&:join)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Wraps open threads and provides a synchronized output buffer for concurrently writing output
|
73
|
+
def thread_mgr
|
74
|
+
@_thread_mgr ||= OpenStruct.new({
|
75
|
+
:threads => [],
|
76
|
+
:lock => Mutex.new
|
77
|
+
})
|
78
|
+
end
|
79
|
+
|
80
|
+
def say_status(status, message, log_status=true)
|
81
|
+
thread_mgr.lock.synchronize {
|
82
|
+
super
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param [String] syscmd The system command to execute
|
87
|
+
# @param [Fixnum] thread_count The numbers of threads to allow running at one time
|
88
|
+
def run_command_in_thread syscmd, thread_count
|
89
|
+
if thread_mgr.threads.size > thread_count then
|
90
|
+
thread_mgr.threads.each(&:join)
|
91
|
+
thread_mgr.threads.clear
|
92
|
+
else
|
93
|
+
thread_mgr.threads << Thread.new(syscmd) do |cmd|
|
94
|
+
begin
|
95
|
+
stdin, stdout, stderr, thread = Open3.popen3(cmd)
|
96
|
+
stdin.close
|
97
|
+
o, e = [stdout, stderr].map {|p| begin p.read ensure p.close end}
|
98
|
+
unless o.empty? then
|
99
|
+
say_status("stdout: #{cmd}", o, :green)
|
100
|
+
end
|
101
|
+
unless e.empty? then
|
102
|
+
say_status("stderr: #{cmd}", e, :red)
|
103
|
+
end
|
104
|
+
if thread then
|
105
|
+
Process.kill('TERM', thread.pid) rescue nil
|
106
|
+
thread.kill unless nil
|
107
|
+
end
|
108
|
+
rescue Exception => e
|
109
|
+
say_status("exception: #{cmd}", e.to_s, :red)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
60
113
|
end
|
61
114
|
|
62
115
|
def asset_get tag, options
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collins_shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.18
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: collins_client
|
@@ -184,7 +184,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
184
184
|
version: '0'
|
185
185
|
segments:
|
186
186
|
- 0
|
187
|
-
hash: -
|
187
|
+
hash: -4494318623502944839
|
188
188
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
189
189
|
none: false
|
190
190
|
requirements:
|