arvicco-avalon 0.0.15 → 0.0.16

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/README.md CHANGED
@@ -16,6 +16,10 @@ Scripts:
16
16
 
17
17
  Monitors all the nodes (miners, pools, Internet connections) that are listed in config/monitor.yml file. Sounds alarm is anything is wrong with the monitored nodes. TODO: takes action to correct errors found (like restarting the failing miners etc).
18
18
 
19
+ $ reset 145 146 192.168.0.150
20
+
21
+ Reboots your Avalon miners. Miners are indicated either by their full IP address or just by the last digits of this address (num). A quick and dirty way to reset misbehaving miners. In some cases of hungup units, soft reset is not enough and a hard powerdown/powerup is required.
22
+
19
23
  $ mtgox_tx
20
24
 
21
25
  Transcodes raw transaction from base64 (mtgox) to hex (blockchain) format
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
- # Script to monitor Avalon miners status and alert if something's wrong
2
+ # Script to monitor minering units status and alert if something's wrong
3
3
 
4
4
  lib = File.expand_path('../../lib', __FILE__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
- require 'yaml'
8
7
  require 'avalon'
9
8
 
10
9
  env = ARGV[0] || 'prod'
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # Script to reboot Avalon miner
3
+
4
+ lib = File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ require 'avalon'
8
+
9
+ Avalon::Config.load 'prod'
10
+
11
+ monitor = Avalon::Monitor.new Avalon::Config[:monitor]
12
+
13
+ ARGV.each do |id|
14
+ miner = monitor.nodes.find {|m| m.num == id}
15
+ miner ||= monitor.nodes.find {|m| m.ip =~ Regexp.new(id)}
16
+ if miner
17
+ miner.reset
18
+ puts "Miner #{id} reset"
19
+ else
20
+ puts "Unable to reset miner #{id}"
21
+ end
22
+ end
@@ -1,5 +1,6 @@
1
1
  require 'pp'
2
2
  require 'time'
3
+ require 'yaml'
3
4
 
4
5
  require "avalon/version"
5
6
  require "avalon/utils"
@@ -32,10 +32,11 @@ module Avalon
32
32
  # Last share converter (Miner-specific)
33
33
  def self.convert_last x
34
34
  y = x[/(?<=Last Share Time=)[\d\.]*/]
35
- if y
36
- my_time(Time.now.getgm-y.to_i, :relative_time)
37
- else
35
+ # p x, y
36
+ if y.nil? || y == '0'
38
37
  "never"
38
+ else
39
+ my_time(Time.now.getgm-y.to_i, :relative_time)
39
40
  end
40
41
  end
41
42
 
@@ -46,7 +47,6 @@ module Avalon
46
47
 
47
48
  def initialize ip, min_speed
48
49
  @ip = ip
49
- @num = ip.split('.').last.to_i
50
50
  @min_speed = min_speed * 1000 # Gh/s to Mh/s
51
51
  @fails = 0
52
52
  @alert_after = Avalon::Config[:alert_after] ||
@@ -89,22 +89,27 @@ module Avalon
89
89
  if data[:ping].nil?
90
90
  @fails += 1
91
91
  if @fails >= @alert_after
92
- alarm "Miner #{@num} did not respond to status query"
92
+ alarm "Miner #{num} did not respond to status query"
93
93
  end
94
94
  else
95
95
  @fails = 0
96
96
  if self[:mhs] < @min_speed and upminutes > 5
97
- alarm "Miner #{@num} performance is #{self[:mhs]}, should be #{@min_speed}"
97
+ alarm "Miner #{num} performance is #{self[:mhs]}, should be #{@min_speed}"
98
98
  elsif self[:temp] >= @alert_temp
99
- alarm "Miner #{@num} too hot at #{self[:temp]}C, needs cooling", "Ping.aiff"
99
+ alarm "Miner #{num} too hot at #{self[:temp]}C, needs cooling", "Ping.aiff"
100
100
  elsif upminutes < 2
101
- alarm "Miner #{@num} restarted", "Frog.aiff"
101
+ alarm "Miner #{num} restarted", "Frog.aiff"
102
102
  end
103
103
  end
104
104
  end
105
105
 
106
+ # Reset or reboot Miner
107
+ def reset
108
+ `ssh root@#{ip} "reboot"`
109
+ end
110
+
106
111
  def to_s
107
- "#{@num}: " + FIELDS.map {|key, (width, _, _ )| @data[key].to_s.ljust(width)}.join(" ")
112
+ "#{num}: " + FIELDS.map {|key, (width, _, _ )| @data[key].to_s.ljust(width)}.join(" ")
108
113
  end
109
114
 
110
115
  end
@@ -2,6 +2,8 @@ module Avalon
2
2
 
3
3
  class Monitor
4
4
 
5
+ attr_reader :nodes
6
+
5
7
  # List of nodes to monitor
6
8
  def initialize opts
7
9
  @nodes = opts[:nodes].map {|args| Avalon::Node.create(*args)}
@@ -11,12 +11,16 @@ module Avalon
11
11
  subclass.new *args.drop(1)
12
12
  end
13
13
 
14
- attr_accessor :data
14
+ attr_reader :ip, :data
15
15
 
16
16
  def initialize
17
17
  @data = {}
18
18
  end
19
19
 
20
+ def num
21
+ @num ||= @ip ? @ip.split('.').last.to_i : ""
22
+ end
23
+
20
24
  # Get a specific data point about this Node
21
25
  def [] key
22
26
  @data[key]
@@ -38,5 +42,10 @@ module Avalon
38
42
  raise "#{self.class} should implement #report"
39
43
  end
40
44
 
45
+ # Abstract: Reset or reboot node
46
+ def reset
47
+ raise "#{self.class} should implement #report"
48
+ end
49
+
41
50
  end
42
51
  end
@@ -1,3 +1,3 @@
1
1
  module Avalon
2
- VERSION = "0.0.15"
2
+ VERSION = "0.0.16"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arvicco-avalon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.16
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: 2013-06-22 00:00:00.000000000 Z
12
+ date: 2013-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -33,6 +33,7 @@ email:
33
33
  executables:
34
34
  - monitor
35
35
  - mtgox_tx
36
+ - reset
36
37
  extensions: []
37
38
  extra_rdoc_files: []
38
39
  files:
@@ -44,6 +45,7 @@ files:
44
45
  - avalon.gemspec
45
46
  - bin/monitor
46
47
  - bin/mtgox_tx
48
+ - bin/reset
47
49
  - lib/avalon.rb
48
50
  - lib/avalon/bitcoind.rb
49
51
  - lib/avalon/block.rb