knife-batch 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -119,20 +119,7 @@ class Batch < Chef::Knife
119
119
  end
120
120
  (ui.fatal("No nodes returned from search!"); exit 10) if list.length == 0
121
121
 
122
- parent_ary = Array.new
123
- child_ary = Array.new
124
- iter = 0
125
- list.each do |item|
126
- if (iter +=1) <= config[:batch_size].to_i
127
- child_ary << item
128
- else
129
- parent_ary << child_ary
130
- child_ary = Array.new
131
- iter = 0
132
- end
133
- end
134
-
135
- parent_ary
122
+ list.each_slice(config[:batch_size].to_i).to_a
136
123
  end
137
124
 
138
125
  def print_data(host, data)
@@ -1,5 +1,5 @@
1
1
  module Knife
2
2
  module Batch
3
- VERSION = "1.0.0"
3
+ VERSION = "1.0.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,65 +1,71 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: knife-batch
3
- version: !ruby/object:Gem::Version
4
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 1.0.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Ian Meyer
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-15 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
12
+
13
+ date: 2011-10-16 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
15
16
  name: chef
16
- requirement: &70191053580660 !ruby/object:Gem::Requirement
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
17
19
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
22
24
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70191053580660
25
- description: ! '`knife batch` is a wonderful little plugin for executing commands
26
- a la `knife ssh`, but doing it in groups of `n` with a sleep between execution iterations.'
27
- email:
25
+ version_requirements: *id001
26
+ description: `knife batch` is a wonderful little plugin for executing commands a la `knife ssh`, but doing it in groups of `n` with a sleep between execution iterations.
27
+ email:
28
28
  - ianmmeyer@gmail.com
29
29
  executables: []
30
+
30
31
  extensions: []
32
+
31
33
  extra_rdoc_files: []
32
- files:
34
+
35
+ files:
33
36
  - .gitignore
34
37
  - Gemfile
35
38
  - README.markdown
36
39
  - Rakefile
37
40
  - knife-batch.gemspec
38
41
  - lib/chef/knife/batch.rb
39
- - lib/chef/knife/knife-batch.rb
40
42
  - lib/knife-batch/version.rb
41
43
  homepage: http://github.com/imeyer/knife-batch
42
44
  licenses: []
45
+
43
46
  post_install_message:
44
47
  rdoc_options: []
45
- require_paths:
48
+
49
+ require_paths:
46
50
  - lib
47
- required_ruby_version: !ruby/object:Gem::Requirement
51
+ required_ruby_version: !ruby/object:Gem::Requirement
48
52
  none: false
49
- requirements:
50
- - - ! '>='
51
- - !ruby/object:Gem::Version
52
- version: '0'
53
- required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
58
  none: false
55
- requirements:
56
- - - ! '>='
57
- - !ruby/object:Gem::Version
58
- version: '0'
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
59
63
  requirements: []
64
+
60
65
  rubyforge_project: knife-batch
61
66
  rubygems_version: 1.8.5
62
67
  signing_key:
63
68
  specification_version: 3
64
69
  summary: Knife plugin to run ssh commands against batches of servers
65
70
  test_files: []
71
+
@@ -1,213 +0,0 @@
1
- #
2
- # Author:: Ian Meyer <ianmmeyer@gmail.com>
3
- # Plugin name:: batch
4
- #
5
- # Copyright 2011, Ian Meyer
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- class Batch < Chef::Knife
21
- banner "knife batch [QUERY] [CMD]"
22
-
23
- deps do
24
- require 'net/ssh'
25
- require 'net/ssh/multi'
26
- require 'readline'
27
- require 'chef/search/query'
28
- require 'chef/mixin/command'
29
- end
30
-
31
- option :wait,
32
- :short => "-W SECONDS",
33
- :long => "--wait SECONDS",
34
- :description => "The number of seconds between batches.",
35
- :default => 0.5
36
-
37
- option :batch_size,
38
- :short => "-B NODES",
39
- :long => "--batch-size NODES",
40
- :description => "The number of nodes to run per batch.",
41
- :default => 5
42
-
43
- option :stop_on_failure,
44
- :short => "-S",
45
- :long => "--stop-on-failure",
46
- :description => "Stop on first failure of remote command",
47
- :default => false
48
-
49
- option :manual,
50
- :short => "-m",
51
- :long => "--manual-list",
52
- :boolean => true,
53
- :description => "QUERY is a space separated list of servers",
54
- :default => false
55
-
56
- option :ssh_user,
57
- :short => "-x USERNAME",
58
- :long => "--ssh-user USERNAME",
59
- :description => "The ssh username"
60
-
61
- option :ssh_password,
62
- :short => "-P PASSWORD",
63
- :long => "--ssh-password PASSWORD",
64
- :description => "The ssh password"
65
-
66
- option :ssh_port,
67
- :short => "-p PORT",
68
- :long => "--ssh-port PORT",
69
- :description => "The ssh port",
70
- :default => "22",
71
- :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
72
-
73
- option :identity_file,
74
- :short => "-i IDENTITY_FILE",
75
- :long => "--identity-file IDENTITY_FILE",
76
- :description => "The SSH identity file used for authentication"
77
-
78
- option :no_host_key_verify,
79
- :long => "--no-host-key-verify",
80
- :description => "Disable host key verification",
81
- :boolean => true,
82
- :default => false
83
-
84
- option :attribute,
85
- :short => "-a ATTR",
86
- :long => "--attribute ATTR",
87
- :description => "The attribute to use for opening the connection - default is fqdn",
88
- :default => "fqdn"
89
-
90
- def session(nodes)
91
- ssh_error_handler = Proc.new do |server|
92
- if config[:manual]
93
- node_name = server.host
94
- else
95
- nodes.each do |n|
96
- node_name = n if format_for_display(n)[config[:attribute]] == server.host
97
- end
98
- end
99
- ui.warn "Failed to connect to #{node_name} -- #{$!.class.name}: #{$!.message}"
100
- $!.backtrace.each { |l| Chef::Log.debug(l) }
101
- end
102
-
103
- @ssh_session ||= Net::SSH::Multi.start(:concurrent_connections => config[:concurrency], :on_error => ssh_error_handler)
104
- end
105
-
106
- def get_nodes
107
- list = case config[:manual]
108
- when true
109
- @name_args[0].split(" ")
110
- when false
111
- r = Array.new
112
- q = Chef::Search::Query.new
113
- @action_nodes = q.search(:node, @name_args[0])[0]
114
- @action_nodes.each do |item|
115
- i = format_for_display(item)[config[:attribute]]
116
- r.push(i) unless i.nil?
117
- end
118
- r
119
- end
120
- (ui.fatal("No nodes returned from search!"); exit 10) if list.length == 0
121
-
122
- parent_ary = Array.new
123
- child_ary = Array.new
124
- iter = 0
125
- list.each do |item|
126
- if (iter +=1) <= config[:batch_size].to_i
127
- child_ary << item
128
- else
129
- parent_ary << child_ary
130
- child_ary = Array.new
131
- iter = 0
132
- end
133
- end
134
-
135
- parent_ary
136
- end
137
-
138
- def print_data(host, data)
139
- if data =~ /\n/
140
- data.split(/\n/).each { |d| print_data(host, d) }
141
- else
142
- padding = @longest - host.length
143
- print ui.color(host, :cyan)
144
- padding.downto(0) { print " " }
145
- puts data
146
- end
147
- end
148
-
149
- def session_from_list(nodes)
150
- nodes.each do |item|
151
- Chef::Log.debug("Adding #{item}")
152
-
153
- hostspec = config[:ssh_user] ? "#{config[:ssh_user]}@#{item}" : item
154
- session_opts = {}
155
- session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file]
156
- session_opts[:password] = config[:ssh_password] if config[:ssh_password]
157
- session_opts[:port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
158
- session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
159
-
160
- if config[:no_host_key_verify]
161
- session_opts[:paranoid] = false
162
- session_opts[:user_known_hosts_file] = "/dev/null"
163
- end
164
- session(nodes).use(hostspec, session_opts)
165
-
166
- @longest = item.length if item.length > @longest
167
- end
168
-
169
- session(nodes)
170
- end
171
-
172
- def ssh_command(command, subsession=nil, nodes)
173
- subsession ||= session(nodes)
174
- subsession.open_channel do |channel|
175
- host = channel[:host]
176
- channel.request_pty
177
- channel.exec command do |ch, success|
178
- exit_code = nil
179
- raise ArgumentError, "Cannot execute #{command}" unless success
180
- channel.on_data do |ch, data|
181
- print_data(host, data)
182
- end
183
-
184
- if config[:stop_on_failure]
185
- channel.on_request("exit-status") do |ch, data|
186
- exit_code = data.read_long
187
- if not exit_code.nil?
188
- exit 1 if exit_code.to_i > 0
189
- end
190
- end
191
- end
192
- end
193
- end
194
- @ssh_session.loop
195
- @ssh_session = nil
196
- end
197
-
198
- def run
199
- extend Chef::Mixin::Command
200
-
201
- @longest = 0
202
- all_nodes = get_nodes
203
- all_nodes.each do |nodes|
204
- session_from_list(nodes)
205
-
206
- ssh_command(@name_args[1..-1].join(" "), nodes)
207
- puts "*" * 80
208
- puts "Taking a nap for #{config[:wait]} seconds..."
209
- puts "*" * 80
210
- sleep config[:wait].to_f
211
- end
212
- end
213
- end