oxidized 0.24.0 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +4 -0
  3. data/.rubocop.yml +3 -0
  4. data/CHANGELOG.md +26 -2
  5. data/Dockerfile +8 -32
  6. data/README.md +17 -5
  7. data/bin/oxidized +1 -1
  8. data/docs/Configuration.md +41 -3
  9. data/docs/Hooks.md +26 -0
  10. data/docs/Model-Notes/AireOS.md +1 -2
  11. data/docs/Model-Notes/ArbOS.md +1 -2
  12. data/docs/Model-Notes/Comware.md +1 -2
  13. data/docs/Model-Notes/EOS.md +1 -2
  14. data/docs/Model-Notes/JunOS.md +1 -2
  15. data/docs/Model-Notes/Netgear.md +5 -6
  16. data/docs/Model-Notes/Nokia.md +9 -0
  17. data/docs/Model-Notes/README.md +3 -2
  18. data/docs/Model-Notes/VRP-Huawei.md +1 -2
  19. data/docs/Model-Notes/Viptela.md +12 -0
  20. data/docs/Model-Notes/XGS4600-Zyxel.md +1 -2
  21. data/docs/Ruby-API.md +54 -2
  22. data/docs/Supported-OS-Types.md +12 -0
  23. data/extra/oxidized.service +7 -0
  24. data/lib/oxidized/cli.rb +7 -0
  25. data/lib/oxidized/config.rb +3 -0
  26. data/lib/oxidized/core.rb +1 -0
  27. data/lib/oxidized/hook/ciscosparkdiff.rb +11 -17
  28. data/lib/oxidized/hook/slackdiff.rb +5 -11
  29. data/lib/oxidized/hook/xmppdiff.rb +1 -0
  30. data/lib/oxidized/input/ssh.rb +43 -27
  31. data/lib/oxidized/input/telnet.rb +1 -0
  32. data/lib/oxidized/model/acos.rb +2 -2
  33. data/lib/oxidized/model/acsw.rb +6 -6
  34. data/lib/oxidized/model/adtran.rb +22 -0
  35. data/lib/oxidized/model/aen.rb +2 -2
  36. data/lib/oxidized/model/aireos.rb +3 -2
  37. data/lib/oxidized/model/alteonos.rb +2 -2
  38. data/lib/oxidized/model/aos.rb +1 -1
  39. data/lib/oxidized/model/aos7.rb +1 -1
  40. data/lib/oxidized/model/aosw.rb +5 -3
  41. data/lib/oxidized/model/apc_aos.rb +1 -1
  42. data/lib/oxidized/model/arbos.rb +2 -2
  43. data/lib/oxidized/model/asa.rb +8 -2
  44. data/lib/oxidized/model/awplus.rb +1 -1
  45. data/lib/oxidized/model/axos.rb +16 -0
  46. data/lib/oxidized/model/c4cmts.rb +3 -5
  47. data/lib/oxidized/model/casa.rb +1 -1
  48. data/lib/oxidized/model/catos.rb +1 -1
  49. data/lib/oxidized/model/ciscosma.rb +1 -1
  50. data/lib/oxidized/model/ciscosmb.rb +10 -4
  51. data/lib/oxidized/model/comtrol.rb +41 -0
  52. data/lib/oxidized/model/comware.rb +1 -1
  53. data/lib/oxidized/model/coriantgroove.rb +4 -6
  54. data/lib/oxidized/model/cumulus.rb +14 -1
  55. data/lib/oxidized/model/datacom.rb +1 -2
  56. data/lib/oxidized/model/dcnos.rb +1 -1
  57. data/lib/oxidized/model/dellx.rb +76 -0
  58. data/lib/oxidized/model/dlink.rb +2 -2
  59. data/lib/oxidized/model/dnos.rb +3 -1
  60. data/lib/oxidized/model/eciapollo.rb +34 -0
  61. data/lib/oxidized/model/edgecos.rb +1 -0
  62. data/lib/oxidized/model/edgeos.rb +6 -1
  63. data/lib/oxidized/model/eos.rb +3 -2
  64. data/lib/oxidized/model/fiberdriver.rb +1 -1
  65. data/lib/oxidized/model/firebrick.rb +31 -0
  66. data/lib/oxidized/model/firewareos.rb +1 -1
  67. data/lib/oxidized/model/fortios.rb +5 -4
  68. data/lib/oxidized/model/ftos.rb +4 -1
  69. data/lib/oxidized/model/fujitsupy.rb +3 -3
  70. data/lib/oxidized/model/gaiaos.rb +1 -1
  71. data/lib/oxidized/model/gcombnps.rb +3 -1
  72. data/lib/oxidized/model/hatteras.rb +1 -1
  73. data/lib/oxidized/model/hirschmann.rb +2 -2
  74. data/lib/oxidized/model/hpebladesystem.rb +1 -1
  75. data/lib/oxidized/model/ios.rb +21 -13
  76. data/lib/oxidized/model/ipos.rb +3 -3
  77. data/lib/oxidized/model/ironware.rb +3 -3
  78. data/lib/oxidized/model/isam.rb +1 -1
  79. data/lib/oxidized/model/junos.rb +1 -1
  80. data/lib/oxidized/model/masteros.rb +2 -3
  81. data/lib/oxidized/model/mlnxos.rb +5 -5
  82. data/lib/oxidized/model/model.rb +3 -0
  83. data/lib/oxidized/model/ndms.rb +1 -2
  84. data/lib/oxidized/model/netgear.rb +7 -9
  85. data/lib/oxidized/model/netonix.rb +1 -1
  86. data/lib/oxidized/model/netscaler.rb +6 -1
  87. data/lib/oxidized/model/nos.rb +2 -2
  88. data/lib/oxidized/model/oneos.rb +1 -1
  89. data/lib/oxidized/model/openbsd.rb +8 -22
  90. data/lib/oxidized/model/openwrt.rb +1 -0
  91. data/lib/oxidized/model/opnsense.rb +1 -1
  92. data/lib/oxidized/model/panos.rb +9 -9
  93. data/lib/oxidized/model/pfsense.rb +2 -1
  94. data/lib/oxidized/model/planet.rb +1 -1
  95. data/lib/oxidized/model/powerconnect.rb +7 -4
  96. data/lib/oxidized/model/procurve.rb +7 -5
  97. data/lib/oxidized/model/routeros.rb +1 -1
  98. data/lib/oxidized/model/saos.rb +1 -1
  99. data/lib/oxidized/model/screenos.rb +3 -3
  100. data/lib/oxidized/model/sros.rb +2 -2
  101. data/lib/oxidized/model/stoneos.rb +1 -1
  102. data/lib/oxidized/model/tmos.rb +2 -0
  103. data/lib/oxidized/model/tplink.rb +4 -0
  104. data/lib/oxidized/model/viptela.rb +29 -0
  105. data/lib/oxidized/model/voltaire.rb +5 -5
  106. data/lib/oxidized/model/voss.rb +4 -4
  107. data/lib/oxidized/model/vrp.rb +1 -1
  108. data/lib/oxidized/model/vyatta.rb +1 -1
  109. data/lib/oxidized/model/weos.rb +1 -1
  110. data/lib/oxidized/model/xos.rb +9 -2
  111. data/lib/oxidized/node.rb +20 -31
  112. data/lib/oxidized/nodes.rb +3 -0
  113. data/lib/oxidized/output/git.rb +17 -20
  114. data/lib/oxidized/output/gitcrypt.rb +2 -1
  115. data/lib/oxidized/output/http.rb +19 -12
  116. data/lib/oxidized/source/csv.rb +15 -8
  117. data/lib/oxidized/source/http.rb +26 -22
  118. data/lib/oxidized/string.rb +9 -4
  119. data/lib/oxidized/version.rb +2 -2
  120. data/lib/oxidized/worker.rb +44 -36
  121. data/oxidized.gemspec +1 -4
  122. metadata +26 -16
@@ -14,10 +14,10 @@ class Voss < Oxidized::Model
14
14
  # Get sys-info and remove information that changes such has temperature and power
15
15
  cmd 'show sys-info' do |cfg|
16
16
  cfg.gsub! /(^((.*)SysUpTime(.*))$)/, 'removed SysUpTime'
17
- cfg.gsub! /^((.*)Temperature Info \:(.*\r?\n){4})/, 'removed Temperature Info and 3 more lines'
18
- cfg.gsub! /(^((.*)AmbientTemperature(.*)\:(.*))$)/, 'removed AmbientTemperature'
19
- cfg.gsub! /(^((.*)Temperature(.*)\:(.*))$)/, 'removed Temperature'
20
- cfg.gsub! /(^((.*)Total Power Usage(.*)\:(.*))$)/, 'removed Total Power Usage'
17
+ cfg.gsub! /^((.*)Temperature Info :(.*\r?\n){4})/, 'removed Temperature Info and 3 more lines'
18
+ cfg.gsub! /(^((.*)AmbientTemperature(.*):(.*))$)/, 'removed AmbientTemperature'
19
+ cfg.gsub! /(^((.*)Temperature(.*):(.*))$)/, 'removed Temperature'
20
+ cfg.gsub! /(^((.*)Total Power Usage(.*):(.*))$)/, 'removed Total Power Usage'
21
21
  comment "#{cfg}\n"
22
22
  end
23
23
 
@@ -11,7 +11,7 @@ class VRP < Oxidized::Model
11
11
  end
12
12
 
13
13
  cmd :all do |cfg|
14
- cfg.each_line.to_a[1..-2].join
14
+ cfg.cut_both
15
15
  end
16
16
 
17
17
  cfg :telnet do
@@ -1,7 +1,7 @@
1
1
  class Vyatta < Oxidized::Model
2
2
  # Brocade Vyatta / VyOS model #
3
3
 
4
- prompt /\@.*?\:~\$\s/
4
+ prompt /@.*?:~\$\s/
5
5
 
6
6
  cmd :all do |cfg|
7
7
  cfg = cfg.lines.to_a[1..-2].join
@@ -4,7 +4,7 @@ class WEOS < Oxidized::Model
4
4
  prompt /^(\s[\w.@-]+[#>]\s?)$/
5
5
 
6
6
  cmd :all do |cfg|
7
- cfg.each_line.to_a[1..-2].join
7
+ cfg.cut_both
8
8
  end
9
9
 
10
10
  cmd 'show running-config' do |cfg|
@@ -27,7 +27,7 @@ class XOS < Oxidized::Model
27
27
  end
28
28
 
29
29
  cmd 'show configuration' do |cfg|
30
- cfg = cfg.each_line.reject { |line| line.match /^#(\s[\w]+\s)(Configuration generated)/ }.join
30
+ cfg = cfg.each_line.reject { |line| line.match /^#(\s[\w -]+\s)(Configuration generated)/ }.join
31
31
  cfg
32
32
  end
33
33
 
@@ -41,7 +41,14 @@ class XOS < Oxidized::Model
41
41
  end
42
42
 
43
43
  cfg :telnet, :ssh do
44
- post_login 'disable clipaging'
44
+ post_login do
45
+ data = cmd 'disable clipaging session'
46
+ match = data.match /^disable clipaging session\n\*?[\w .-]+(:\d+)? # $/m
47
+ next if match
48
+
49
+ cmd 'disable clipaging'
50
+ end
51
+
45
52
  pre_logout do
46
53
  send "exit\n"
47
54
  send "n\n"
@@ -39,6 +39,7 @@ module Oxidized
39
39
  # don't try input if model is missing config block, we may need strong config to class_name map
40
40
  cfg_name = input.to_s.split('::').last.downcase
41
41
  next unless @model.cfg[cfg_name] and not @model.cfg[cfg_name].empty?
42
+
42
43
  @model.input = input = input.new
43
44
  if config = run_input(input)
44
45
  Oxidized.logger.debug "lib/oxidized/node.rb: #{input.class.name} ran for #{name} successfully"
@@ -74,14 +75,17 @@ module Oxidized
74
75
  Oxidized.logger.send(level, '%s raised %s%s with msg "%s"' % [self.ip, err.class, resc, err.message])
75
76
  return false
76
77
  rescue => err
77
- file = Oxidized::Config::Crash + '.' + self.ip.to_s
78
- open file, 'w' do |fh|
78
+ crashdir = Oxidized.config.crash.directory
79
+ crashfile = Oxidized.config.crash.hostnames? ? self.name : self.ip.to_s
80
+ FileUtils.mkdir_p(crashdir) unless File.directory?(crashdir)
81
+
82
+ open File.join(crashdir, crashfile), 'w' do |fh|
79
83
  fh.puts Time.now.utc
80
84
  fh.puts err.message + ' [' + err.class.to_s + ']'
81
85
  fh.puts '-' * 50
82
86
  fh.puts err.backtrace
83
87
  end
84
- Oxidized.logger.error '%s raised %s with msg "%s", %s saved' % [self.ip, err.class, err.message, file]
88
+ Oxidized.logger.error '%s raised %s with msg "%s", %s saved' % [self.ip, err.class, err.message, crashfile]
85
89
  return false
86
90
  end
87
91
  end
@@ -173,32 +177,18 @@ module Oxidized
173
177
  end
174
178
 
175
179
  def resolve_repo opt
176
- if is_git? opt
177
- remote_repo = Oxidized.config.output.git.repo
178
-
179
- if remote_repo.is_a?(::String)
180
- if Oxidized.config.output.git.single_repo? || @group.nil?
181
- remote_repo
182
- else
183
- File.join(File.dirname(remote_repo), @group + '.git')
184
- end
185
- else
186
- remote_repo[@group]
187
- end
188
- elsif is_gitcrypt? opt
189
- remote_repo = Oxidized.config.output.gitcrypt.repo
190
-
191
- if remote_repo.is_a?(::String)
192
- if Oxidized.config.output.gitcrypt.single_repo? || @group.nil?
193
- remote_repo
194
- else
195
- File.join(File.dirname(remote_repo), @group + '.git')
196
- end
180
+ type = git_type opt
181
+ return nil unless type
182
+
183
+ remote_repo = Oxidized.config.output.send(type).repo
184
+ if remote_repo.is_a?(::String)
185
+ if Oxidized.config.output.send(type).single_repo? || @group.nil?
186
+ remote_repo
197
187
  else
198
- remote_repo[@group]
188
+ File.join(File.dirname(remote_repo), @group + '.git')
199
189
  end
200
190
  else
201
- return
191
+ remote_repo[@group]
202
192
  end
203
193
  end
204
194
 
@@ -237,12 +227,11 @@ module Oxidized
237
227
  value
238
228
  end
239
229
 
240
- def is_git? opt
241
- (opt[:output] || Oxidized.config.output.default) == 'git'
242
- end
230
+ def git_type opt
231
+ type = opt[:output] || Oxidized.config.output.default
232
+ return nil unless type[0..2] == "git"
243
233
 
244
- def is_gitcrypt? opt
245
- (opt[:output] || Oxidized.config.output.default) == 'gitcrypt'
234
+ type
246
235
  end
247
236
  end
248
237
  end
@@ -16,6 +16,7 @@ module Oxidized
16
16
  nodes.each do |node|
17
17
  # we want to load specific node(s), not all of them
18
18
  next unless node_want? node_want, node
19
+
19
20
  begin
20
21
  _node = Node.new node
21
22
  new.push _node
@@ -32,6 +33,7 @@ module Oxidized
32
33
 
33
34
  def node_want? node_want, node
34
35
  return true unless node_want
36
+
35
37
  node_want_ip = (IPAddr.new(node_want) rescue false)
36
38
  name_is_ip = (IPAddr.new(node[:name]) rescue false)
37
39
  if name_is_ip and node_want_ip == node[:name]
@@ -173,6 +175,7 @@ module Oxidized
173
175
  node = find { |n| n.name == node_name }
174
176
  output = node.output.new
175
177
  raise Oxidized::NotSupported unless output.respond_to? :fetch
178
+
176
179
  yield node, output
177
180
  end
178
181
  end
@@ -167,7 +167,7 @@ module Oxidized
167
167
 
168
168
  begin
169
169
  repo = Rugged::Repository.new repo
170
- update_repo repo, file, data, @msg, @user, @email
170
+ update_repo repo, file, data
171
171
  rescue Rugged::OSError, Rugged::RepositoryError => open_error
172
172
  begin
173
173
  Rugged::Repository.init_at repo, :bare
@@ -178,27 +178,24 @@ module Oxidized
178
178
  end
179
179
  end
180
180
 
181
- def update_repo repo, file, data, msg, user, email
181
+ def update_repo repo, file, data
182
+ oid_old = repo.blob_at(repo.head.target_id, file) rescue nil
183
+ return false if oid_old and oid_old.content == data
184
+
182
185
  oid = repo.write data, :blob
183
186
  index = repo.index
184
- index.read_tree repo.head.target.tree unless repo.empty?
185
-
186
- tree_old = index.write_tree repo
187
- index.add :path => file, :oid => oid, :mode => 0100644
188
- tree_new = index.write_tree repo
189
-
190
- if tree_old != tree_new
191
- repo.config['user.name'] = user
192
- repo.config['user.email'] = email
193
- @commitref = Rugged::Commit.create(repo,
194
- :tree => index.write_tree(repo),
195
- :message => msg,
196
- :parents => repo.empty? ? [] : [repo.head.target].compact,
197
- :update_ref => 'HEAD',)
198
-
199
- index.write
200
- true
201
- end
187
+ index.add path: file, oid: oid, mode: 0100644
188
+
189
+ repo.config['user.name'] = @user
190
+ repo.config['user.email'] = @email
191
+ @commitref = Rugged::Commit.create(repo,
192
+ tree: index.write_tree(repo),
193
+ message: @msg,
194
+ parents: repo.empty? ? [] : [repo.head.target].compact,
195
+ update_ref: 'HEAD')
196
+
197
+ index.write
198
+ true
202
199
  end
203
200
  end
204
201
  end
@@ -4,7 +4,7 @@ module Oxidized
4
4
  begin
5
5
  require 'git'
6
6
  rescue LoadError
7
- raise OxidizedError, 'git not found: sudo gem install ruby-git'
7
+ raise OxidizedError, 'git not found: sudo gem install git'
8
8
  end
9
9
 
10
10
  attr_reader :commitref
@@ -99,6 +99,7 @@ module Oxidized
99
99
  else
100
100
  File.read path
101
101
  end
102
+
102
103
  lock repo
103
104
  rescue
104
105
  'node not found'
@@ -14,28 +14,19 @@ module Oxidized
14
14
  raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
15
15
  end
16
16
  end
17
+
17
18
  require "net/http"
18
19
  require "uri"
19
20
  require "json"
21
+
20
22
  def store node, outputs, opt = {}
21
23
  @commitref = nil
22
- json = JSON.pretty_generate(
23
- {
24
- 'msg' => opt[:msg],
25
- 'user' => opt[:user],
26
- 'email' => opt[:email],
27
- 'group' => opt[:group],
28
- 'node' => node,
29
- 'config' => outputs.to_cfg,
30
- # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
31
- }
32
- )
33
24
  uri = URI.parse @cfg.url
34
25
  http = Net::HTTP.new uri.host, uri.port
35
26
  # http.use_ssl = true if uri.scheme = 'https'
36
27
  req = Net::HTTP::Post.new(uri.request_uri, initheader = { 'Content-Type' => 'application/json' })
37
28
  req.basic_auth @cfg.user, @cfg.password
38
- req.body = json
29
+ req.body = generate_json(node, outputs, opt)
39
30
  response = http.request req
40
31
 
41
32
  case response.code.to_i
@@ -50,5 +41,21 @@ module Oxidized
50
41
  Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
51
42
  end
52
43
  end
44
+
45
+ private
46
+
47
+ def generate_json node, outputs, opt
48
+ JSON.pretty_generate(
49
+ {
50
+ 'msg' => opt[:msg],
51
+ 'user' => opt[:user],
52
+ 'email' => opt[:email],
53
+ 'group' => opt[:group],
54
+ 'node' => node,
55
+ 'config' => outputs.to_cfg,
56
+ # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
57
+ }
58
+ )
59
+ end
53
60
  end
54
61
  end
@@ -20,17 +20,12 @@ module Oxidized
20
20
 
21
21
  def load _node_want = nil
22
22
  nodes = []
23
- file = File.expand_path(@cfg.file)
24
- file = if @cfg.gpg?
25
- crypto = GPGME::Crypto.new password: @cfg.gpg_password
26
- file = crypto.decrypt(File.open(file)).to_s
27
- else
28
- open(file)
29
- end
30
- file.each_line do |line|
23
+ open_file.each_line do |line|
31
24
  next if line.match(/^\s*#/)
25
+
32
26
  data = line.chomp.split(@cfg.delimiter, -1)
33
27
  next if data.empty?
28
+
34
29
  # map node parameters
35
30
  keys = {}
36
31
  @cfg.map.each do |key, position|
@@ -49,5 +44,17 @@ module Oxidized
49
44
  end
50
45
  nodes
51
46
  end
47
+
48
+ private
49
+
50
+ def open_file
51
+ file = File.expand_path(@cfg.file)
52
+ if @cfg.gpg?
53
+ crypto = GPGME::Crypto.new password: @cfg.gpg_password
54
+ crypto.decrypt(File.open(file)).to_s
55
+ else
56
+ open(file)
57
+ end
58
+ end
52
59
  end
53
60
  end
@@ -12,36 +12,17 @@ module Oxidized
12
12
  end
13
13
 
14
14
  require "net/http"
15
+ require "net/https"
15
16
  require "uri"
16
17
  require "json"
17
18
 
18
19
  def load node_want = nil
19
20
  nodes = []
20
- uri = URI.parse(@cfg.url)
21
- http = Net::HTTP.new(uri.host, uri.port)
22
- http.use_ssl = true if uri.scheme == 'https'
23
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
24
-
25
- # map headers
26
- headers = {}
27
- @cfg.headers.each do |header, value|
28
- headers[header] = value
29
- end
30
-
31
- req_uri = uri.request_uri
32
- if node_want
33
- req_uri = "#{req_uri}/#{node_want}"
34
- end
35
- request = Net::HTTP::Get.new(req_uri, headers)
36
- if (@cfg.user? && @cfg.pass?)
37
- request.basic_auth(@cfg.user, @cfg.pass)
38
- end
39
-
40
- response = http.request(request)
41
- data = JSON.parse(response.body)
21
+ data = JSON.parse(read_http(node_want))
42
22
  data = string_navigate(data, @cfg.hosts_location) if @cfg.hosts_location?
43
23
  data.each do |node|
44
24
  next if node.empty?
25
+
45
26
  # map node parameters
46
27
  keys = {}
47
28
  @cfg.map.each do |key, want_position|
@@ -72,5 +53,28 @@ module Oxidized
72
53
  end
73
54
  object
74
55
  end
56
+
57
+ def read_http node_want
58
+ uri = URI.parse(@cfg.url)
59
+ http = Net::HTTP.new(uri.host, uri.port)
60
+ http.use_ssl = true if uri.scheme == 'https'
61
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @cfg.secure
62
+
63
+ # map headers
64
+ headers = {}
65
+ @cfg.headers.each do |header, value|
66
+ headers[header] = value
67
+ end
68
+
69
+ req_uri = uri.request_uri
70
+ if node_want
71
+ req_uri = "#{req_uri}/#{node_want}"
72
+ end
73
+ request = Net::HTTP::Get.new(req_uri, headers)
74
+ if (@cfg.user? && @cfg.pass?)
75
+ request.basic_auth(@cfg.user, @cfg.pass)
76
+ end
77
+ http.request(request).body
78
+ end
75
79
  end
76
80
  end
@@ -4,13 +4,18 @@ module Oxidized
4
4
  attr_accessor :type, :cmd, :name
5
5
 
6
6
  # @return [Oxidized::String] copy of self with last line removed
7
- def cut_tail
8
- Oxidized::String.new each_line.to_a[0..-2].join
7
+ def cut_tail lines = 1
8
+ Oxidized::String.new each_line.to_a[0..-1 - lines].join
9
9
  end
10
10
 
11
11
  # @return [Oxidized::String] copy of self with first line removed
12
- def cut_head
13
- Oxidized::String.new each_line.to_a[1..-1].join
12
+ def cut_head lines = 1
13
+ Oxidized::String.new each_line.to_a[lines..-1].join
14
+ end
15
+
16
+ # @return [Oxidized::String] copy of self with first and last lines removed
17
+ def cut_both head = 1, tail = 1
18
+ Oxidized::String.new each_line.to_a[head..-1 - tail].join
14
19
  end
15
20
 
16
21
  # sets @cmd and @name unless @name is already set
@@ -1,6 +1,6 @@
1
1
  module Oxidized
2
- VERSION = '0.24.0'
3
- VERSION_FULL = '0.24.0'
2
+ VERSION = '0.25.0'
3
+ VERSION_FULL = '0.25.0'
4
4
  def self.version_set
5
5
  version_full = %x(git describe --tags).chop rescue ""
6
6
  version = %x(git describe --tags --abbrev=0).chop rescue ""
@@ -28,8 +28,9 @@ module Oxidized
28
28
  # shift nodes and get the next node
29
29
  node = @nodes.get
30
30
  node.running? ? next : node.running = true
31
+
31
32
  @jobs.push Job.new node
32
- Oxidized.logger.debug "lib/oxidized/worker.rb: Added #{node.name} to the job queue"
33
+ Oxidized.logger.debug "lib/oxidized/worker.rb: Added #{node.group}/#{node.name} to the job queue"
33
34
  end
34
35
 
35
36
  run_done_hook if is_cycle_finished?
@@ -42,49 +43,56 @@ module Oxidized
42
43
  node.stats.add job
43
44
  @jobs.duration job.time
44
45
  node.running = false
45
-
46
46
  if job.status == :success
47
- @jobs_done += 1 # needed for :nodes_done hook
48
- Oxidized.Hooks.handle :node_success, :node => node,
49
- :job => job
50
- msg = "update #{node.name}"
51
- msg += " from #{node.from}" if node.from
52
- msg += " with message '#{node.msg}'" if node.msg
53
- output = node.output.new
54
- if output.store node.name, job.config,
55
- :msg => msg, :email => node.email, :user => node.user, :group => node.group
56
- node.modified
57
- Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
58
- Oxidized.Hooks.handle :post_store, :node => node,
59
- :job => job,
60
- :commitref => output.commitref
61
- end
62
- node.reset
47
+ process_success node, job
63
48
  else
64
- msg = "#{node.name} status #{job.status}"
65
- if node.retry < Oxidized.config.retries
66
- node.retry += 1
67
- msg += ", retry attempt #{node.retry}"
68
- @nodes.next node.name
69
- else
70
- # Only increment the @jobs_done when we give up retries for a node (or success).
71
- # As it would otherwise cause @jobs_done to be incremented with generic retries.
72
- # This would cause :nodes_done hook to desync from running at the end of the nodelist and
73
- # be fired when the @jobs_done > @nodes.count (could be mid-cycle on the next cycle).
74
- @jobs_done += 1
75
- msg += ", retries exhausted, giving up"
76
- node.retry = 0
77
- Oxidized.Hooks.handle :node_fail, :node => node,
78
- :job => job
79
- end
80
- Oxidized.logger.warn msg
49
+ process_failure node, job
81
50
  end
82
51
  rescue NodeNotFound
83
- Oxidized.logger.warn "#{node.name} not found, removed while collecting?"
52
+ Oxidized.logger.warn "#{node.group}/#{node.name} not found, removed while collecting?"
84
53
  end
85
54
 
86
55
  private
87
56
 
57
+ def process_success node, job
58
+ @jobs_done += 1 # needed for :nodes_done hook
59
+ Oxidized.Hooks.handle :node_success, node: node,
60
+ job: job
61
+ msg = "update #{node.group}/#{node.name}"
62
+ msg += " from #{node.from}" if node.from
63
+ msg += " with message '#{node.msg}'" if node.msg
64
+ output = node.output.new
65
+ if output.store node.name, job.config,
66
+ msg: msg, email: node.email, user: node.user, group: node.group
67
+ node.modified
68
+ Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
69
+ Oxidized.Hooks.handle :post_store, node: node,
70
+ job: job,
71
+ commitref: output.commitref
72
+ end
73
+ node.reset
74
+ end
75
+
76
+ def process_failure node, job
77
+ msg = "#{node.group}/#{node.name} status #{job.status}"
78
+ if node.retry < Oxidized.config.retries
79
+ node.retry += 1
80
+ msg += ", retry attempt #{node.retry}"
81
+ @nodes.next node.name
82
+ else
83
+ # Only increment the @jobs_done when we give up retries for a node (or success).
84
+ # As it would otherwise cause @jobs_done to be incremented with generic retries.
85
+ # This would cause :nodes_done hook to desync from running at the end of the nodelist and
86
+ # be fired when the @jobs_done > @nodes.count (could be mid-cycle on the next cycle).
87
+ @jobs_done += 1
88
+ msg += ", retries exhausted, giving up"
89
+ node.retry = 0
90
+ Oxidized.Hooks.handle :node_fail, :node => node,
91
+ :job => job
92
+ end
93
+ Oxidized.logger.warn msg
94
+ end
95
+
88
96
  def is_cycle_finished?
89
97
  if @jobs_done > @nodes.count
90
98
  true