arvicco-avalon 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
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