knife-batch 1.0.0 → 1.0.2

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