zold 0.11.16 → 0.11.17
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.
- checksums.yaml +4 -4
- data/.rultor.yml +3 -1
- data/bin/zold-nohup +2 -0
- data/heroku.yml +9 -0
- data/lib/zold/commands/node.rb +50 -13
- data/lib/zold/commands/remote.rb +27 -0
- data/lib/zold/commands/taxes.rb +1 -1
- data/lib/zold/remotes.rb +5 -1
- data/lib/zold/routines.rb +58 -0
- data/lib/zold/version.rb +1 -1
- data/resources/remotes +0 -1
- data/test/commands/test_remote.rb +19 -0
- data/test/test_routines.rb +41 -0
- metadata +5 -2
- data/Procfile +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c756ab9df322c31f1b31c030d2f6f56971d2ef36
|
4
|
+
data.tar.gz: c03dc1d19510c459ed571a40e60d1e47d3ececd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2f402cb7258a1f85966d2f9a46e15b4a12d44eccc1150259208221a98141553511b23fbec78d93a780af64a59fe94f3c58a36ab8862e442bd1b76313406eac7
|
7
|
+
data.tar.gz: 682b3ad6c5bdec21e0eb95d94c7bac6dd04ad0776027cb96716bfef916bdbb4f4ec935e84f9832b26bc05fe684cb9b7968cd0c7ddfcd3203aabd1909a3061747
|
data/.rultor.yml
CHANGED
@@ -2,6 +2,7 @@ assets:
|
|
2
2
|
rubygems.yml: zerocracy/home#assets/rubygems.yml
|
3
3
|
id_rsa: zerocracy/home#assets/heroku-key
|
4
4
|
id_rsa.pub: zerocracy/home#assets/heroku-key.pub
|
5
|
+
bonus.key: zerocracy/home#assets/zold/bonus.key
|
5
6
|
install: |
|
6
7
|
sudo apt-get -y update
|
7
8
|
sudo gem install pdd
|
@@ -28,7 +29,8 @@ release:
|
|
28
29
|
git add Gemfile.lock
|
29
30
|
git add .gitignore
|
30
31
|
git fetch
|
31
|
-
|
32
|
+
cp ../bonus.key . && git add bonus.key
|
33
|
+
git commit -m 'config' && git push -f heroku $(git symbolic-ref --short HEAD):master
|
32
34
|
curl -f --connect-timeout 15 --retry 5 --retry-delay 30 http://b1.zold.io > /dev/null
|
33
35
|
architect:
|
34
36
|
- yegor256
|
data/bin/zold-nohup
CHANGED
@@ -38,6 +38,7 @@ end
|
|
38
38
|
|
39
39
|
def exec(cmd)
|
40
40
|
Open3.popen2e(cmd) do |stdin, stdout, thr|
|
41
|
+
log("Started: #{cmd}")
|
41
42
|
stdin.close
|
42
43
|
loop do
|
43
44
|
line = stdout.gets
|
@@ -45,6 +46,7 @@ def exec(cmd)
|
|
45
46
|
log(line)
|
46
47
|
end
|
47
48
|
code = thr.value.exitstatus
|
49
|
+
log("Exit code is #{code}: #{cmd}")
|
48
50
|
raise "Exit code #{code} (non zero)" unless code.zero?
|
49
51
|
end
|
50
52
|
end
|
data/heroku.yml
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
build:
|
2
|
+
languages:
|
3
|
+
- ruby
|
4
|
+
run:
|
5
|
+
web: |
|
6
|
+
LC_ALL=UTF-8 ./bin/zold node --no-colors --verbose --trace \
|
7
|
+
--bind-port=$PORT --port=80 --host=b1.zold.io --threads=0 \
|
8
|
+
--invoice=JKFq17yipfjLtX@0000000000000000 --never-reboot \
|
9
|
+
--bonus-wallet=81c9c25789b03876 --private-key=bonus.key --bonus-amount=1
|
data/lib/zold/commands/node.rb
CHANGED
@@ -20,12 +20,15 @@
|
|
20
20
|
|
21
21
|
require 'slop'
|
22
22
|
require_relative '../score'
|
23
|
+
require_relative '../routines'
|
23
24
|
require_relative '../wallets'
|
24
25
|
require_relative '../remotes'
|
25
26
|
require_relative '../verbose_thread'
|
26
27
|
require_relative '../node/entrance'
|
27
28
|
require_relative '../node/front'
|
28
29
|
require_relative '../node/farm'
|
30
|
+
require_relative 'push'
|
31
|
+
require_relative 'pay'
|
29
32
|
|
30
33
|
# NODE command.
|
31
34
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -68,6 +71,14 @@ module Zold
|
|
68
71
|
o.bool '--never-reboot',
|
69
72
|
'Don\'t reboot when a new version shows up in the network',
|
70
73
|
default: false
|
74
|
+
o.string '--bonus-wallet',
|
75
|
+
'The ID of the wallet to regularly send bonuses from (for nodes online)'
|
76
|
+
o.string '--bonus-amount',
|
77
|
+
'The amount of ZLD to pay to each remote as a bonus',
|
78
|
+
default: '1'
|
79
|
+
o.string '--private-key',
|
80
|
+
'The location of RSA private key (default: ~/.ssh/id_rsa)',
|
81
|
+
default: '~/.ssh/id_rsa'
|
71
82
|
o.bool '--help', 'Print instructions'
|
72
83
|
end
|
73
84
|
if opts.help?
|
@@ -117,25 +128,51 @@ module Zold
|
|
117
128
|
threads: opts[:threads], strength: opts[:strength]
|
118
129
|
)
|
119
130
|
Front.set(:farm, farm)
|
120
|
-
|
121
|
-
VerboseThread.new(@log).run(true) do
|
122
|
-
loop do
|
123
|
-
sleep(60)
|
124
|
-
require_relative 'remote'
|
125
|
-
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote add b1.zold.io 80 --force])
|
126
|
-
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote trim])
|
127
|
-
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote update --reboot])
|
128
|
-
@log.info("Regular update of remote nodes succeeded, total=#{remotes.all.count}")
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
131
|
+
routines = routines(wallets, remotes, farm, opts)
|
132
132
|
@log.debug("Starting up the web front at http://#{opts[:host]}:#{opts[:port]}...")
|
133
133
|
begin
|
134
134
|
Front.run!
|
135
135
|
ensure
|
136
136
|
farm.stop
|
137
|
-
|
137
|
+
routines.stop
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def routines(wallets, remotes, farm, opts)
|
144
|
+
routines = Routines.new(@log)
|
145
|
+
routines.add do
|
146
|
+
require_relative 'remote'
|
147
|
+
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote add b1.zold.io 80 --force])
|
148
|
+
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote trim])
|
149
|
+
Remote.new(remotes: remotes, log: @log, farm: farm).run(%w[remote update --reboot])
|
150
|
+
end
|
151
|
+
if opts['bonus-wallet']
|
152
|
+
routines.add do
|
153
|
+
require_relative 'remote'
|
154
|
+
winners = Remote.new(remotes: remotes, log: @log, farm: farm).run(
|
155
|
+
['remote', 'elect', opts['bonus-wallet'], '--private-key', opts['private-key']]
|
156
|
+
)
|
157
|
+
if winners.empty?
|
158
|
+
@log.info('No winners elected, won\'t pay any bonuses')
|
159
|
+
else
|
160
|
+
winners.each do |score|
|
161
|
+
Pay.new(wallets: wallets, remotes: remotes, log: @log).run(
|
162
|
+
[
|
163
|
+
'pay', opts['bonus-wallet'], score.invoice, opts['bonus-amount'],
|
164
|
+
"Hosting bonus for #{score.host}:#{score.port} #{score.value}",
|
165
|
+
'--private-key', opts['private-key']
|
166
|
+
]
|
167
|
+
)
|
168
|
+
Push.new(wallets: wallets, remotes: remotes, log: @log).run(
|
169
|
+
['push', opts['bonus-wallet']]
|
170
|
+
)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
138
174
|
end
|
175
|
+
routines
|
139
176
|
end
|
140
177
|
|
141
178
|
# Fake logging facility for Webrick
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -58,6 +58,8 @@ Available commands:
|
|
58
58
|
Add a new remote node
|
59
59
|
#{Rainbow('remote remove').green} host [port]
|
60
60
|
Remove the remote node
|
61
|
+
#{Rainbow('remote elect').green}
|
62
|
+
Pick a random remote node as a target for a bonus awarding
|
61
63
|
#{Rainbow('remote trim').green}
|
62
64
|
Remote the least reliable nodes
|
63
65
|
#{Rainbow('remote update').green}
|
@@ -66,6 +68,9 @@ Available options:"
|
|
66
68
|
o.bool '--ignore-score-weakness',
|
67
69
|
'Don\'t complain when their score is too weak',
|
68
70
|
default: false
|
71
|
+
o.bool '--ignore-score-value',
|
72
|
+
'Don\'t complain when their score is too small',
|
73
|
+
default: false
|
69
74
|
o.bool '--force',
|
70
75
|
'Add/remove if if this operation is not possible',
|
71
76
|
default: false
|
@@ -88,6 +93,8 @@ Available options:"
|
|
88
93
|
add(mine[1], mine[2] ? mine[2].to_i : Remotes::PORT, opts)
|
89
94
|
when 'remove'
|
90
95
|
remove(mine[1], mine[2] ? mine[2].to_i : Remotes::PORT, opts)
|
96
|
+
when 'elect'
|
97
|
+
elect(opts)
|
91
98
|
when 'trim'
|
92
99
|
trim(opts)
|
93
100
|
when 'update'
|
@@ -139,6 +146,26 @@ Available options:"
|
|
139
146
|
@log.info("There are #{@remotes.all.count} remote nodes in the list")
|
140
147
|
end
|
141
148
|
|
149
|
+
# Returns an array of Zold::Score
|
150
|
+
def elect(opts)
|
151
|
+
scores = []
|
152
|
+
@remotes.all.sample(1).each do |winner|
|
153
|
+
@remotes.iterate(@log, farm: @farm) do |r|
|
154
|
+
next if r.host != winner[:host] || r.port != winner[:port]
|
155
|
+
res = r.http('/').get
|
156
|
+
r.assert_code(200, res)
|
157
|
+
score = Score.parse_json(JSON.parse(res.body)['score'])
|
158
|
+
r.assert_valid_score(score)
|
159
|
+
r.assert_score_ownership(score)
|
160
|
+
r.assert_score_strength(score) unless opts['ignore-score-weakness']
|
161
|
+
r.assert_score_value(score, Tax::EXACT_SCORE) unless opts['ignore-score-value']
|
162
|
+
@log.info("Elected: #{score}")
|
163
|
+
scores << score
|
164
|
+
end
|
165
|
+
end
|
166
|
+
scores
|
167
|
+
end
|
168
|
+
|
142
169
|
def trim(opts)
|
143
170
|
@remotes.all.each do |r|
|
144
171
|
remove(r[:host], r[:port], opts) if r[:errors] > Remotes::TOLERANCE
|
data/lib/zold/commands/taxes.rb
CHANGED
@@ -124,7 +124,7 @@ Available options:"
|
|
124
124
|
score = Score.parse_json(json['score'])
|
125
125
|
r.assert_valid_score(score)
|
126
126
|
r.assert_score_strength(score)
|
127
|
-
|
127
|
+
r.assert_score_value(score, Tax::EXACT_SCORE)
|
128
128
|
@log.info("#{r}: #{Rainbow(score.value).green}")
|
129
129
|
best << score
|
130
130
|
end
|
data/lib/zold/remotes.rb
CHANGED
@@ -87,7 +87,11 @@ module Zold
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def assert_score_strength(score)
|
90
|
-
raise "Score is too weak #{score.strength}" if score.strength < Score::STRENGTH
|
90
|
+
raise "Score is too weak #{score.strength}: #{score}" if score.strength < Score::STRENGTH
|
91
|
+
end
|
92
|
+
|
93
|
+
def assert_score_value(score, min)
|
94
|
+
raise "Score is too small (<#{min}): #{score}" if score.value < min
|
91
95
|
end
|
92
96
|
end
|
93
97
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
11
|
+
# copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
# SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'log'
|
22
|
+
require_relative 'verbose_thread'
|
23
|
+
|
24
|
+
# Background routines.
|
25
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
26
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
27
|
+
# License:: MIT
|
28
|
+
module Zold
|
29
|
+
# NODE command
|
30
|
+
class Routines
|
31
|
+
def initialize(log = Log::Quiet.new)
|
32
|
+
@log = log
|
33
|
+
@threads = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def add(seconds = 60)
|
37
|
+
@threads << Thread.start do
|
38
|
+
VerboseThread.new(@log).run(true) do
|
39
|
+
Thread.current.name = 'routines'
|
40
|
+
count = 0
|
41
|
+
loop do
|
42
|
+
sleep(seconds)
|
43
|
+
yield count
|
44
|
+
count += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def stop
|
51
|
+
@threads.each do |t|
|
52
|
+
t.exit
|
53
|
+
@log.debug("#{t.name} thread stopped")
|
54
|
+
end
|
55
|
+
@log.info("#{@threads.count} routine threads stopped")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/zold/version.rb
CHANGED
data/resources/remotes
CHANGED
@@ -69,4 +69,23 @@ class TestRemote < Minitest::Test
|
|
69
69
|
assert_equal(4, remotes.all.count)
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
def test_elects_a_remote
|
74
|
+
Dir.mktmpdir 'test' do |dir|
|
75
|
+
zero = Zold::Score::ZERO
|
76
|
+
remotes = Zold::Remotes.new(File.join(dir, 'remotes.txt'))
|
77
|
+
remotes.clean
|
78
|
+
remotes.add(zero.host, zero.port)
|
79
|
+
stub_request(:get, "http://#{zero.host}:#{zero.port}/").to_return(
|
80
|
+
status: 200,
|
81
|
+
body: {
|
82
|
+
version: Zold::VERSION,
|
83
|
+
score: zero.to_h
|
84
|
+
}.to_json
|
85
|
+
)
|
86
|
+
cmd = Zold::Remote.new(remotes: remotes, log: test_log)
|
87
|
+
winners = cmd.run(%w[remote elect --ignore-score-value])
|
88
|
+
assert_equal(1, winners.count)
|
89
|
+
end
|
90
|
+
end
|
72
91
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
11
|
+
# copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
# SOFTWARE.
|
20
|
+
|
21
|
+
require 'minitest/autorun'
|
22
|
+
require_relative 'test__helper'
|
23
|
+
require_relative '../lib/zold/routines'
|
24
|
+
|
25
|
+
# Routines test.
|
26
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
28
|
+
# License:: MIT
|
29
|
+
class TestRoutines < Minitest::Test
|
30
|
+
def test_start_and_stop
|
31
|
+
routines = Zold::Routines.new
|
32
|
+
list = []
|
33
|
+
routines.add(0) do |i|
|
34
|
+
list << i
|
35
|
+
sleep(6000)
|
36
|
+
end
|
37
|
+
sleep 0.1 while list.empty?
|
38
|
+
routines.stop
|
39
|
+
assert_equal(1, list.count)
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -296,7 +296,6 @@ files:
|
|
296
296
|
- Gemfile
|
297
297
|
- INSTALL.md
|
298
298
|
- LICENSE.txt
|
299
|
-
- Procfile
|
300
299
|
- README.md
|
301
300
|
- Rakefile
|
302
301
|
- appveyor.yml
|
@@ -318,6 +317,7 @@ files:
|
|
318
317
|
- fixtures/scripts/calculate-scores.sh
|
319
318
|
- fixtures/scripts/print-helps.sh
|
320
319
|
- fixtures/scripts/push-and-pull.sh
|
320
|
+
- heroku.yml
|
321
321
|
- lib/zold.rb
|
322
322
|
- lib/zold/amount.rb
|
323
323
|
- lib/zold/atomic_file.rb
|
@@ -351,6 +351,7 @@ files:
|
|
351
351
|
- lib/zold/patch.rb
|
352
352
|
- lib/zold/prefixes.rb
|
353
353
|
- lib/zold/remotes.rb
|
354
|
+
- lib/zold/routines.rb
|
354
355
|
- lib/zold/score.rb
|
355
356
|
- lib/zold/signature.rb
|
356
357
|
- lib/zold/tax.rb
|
@@ -392,6 +393,7 @@ files:
|
|
392
393
|
- test/test_patch.rb
|
393
394
|
- test/test_prefixes.rb
|
394
395
|
- test/test_remotes.rb
|
396
|
+
- test/test_routines.rb
|
395
397
|
- test/test_score.rb
|
396
398
|
- test/test_signature.rb
|
397
399
|
- test/test_tax.rb
|
@@ -463,6 +465,7 @@ test_files:
|
|
463
465
|
- test/test_patch.rb
|
464
466
|
- test/test_prefixes.rb
|
465
467
|
- test/test_remotes.rb
|
468
|
+
- test/test_routines.rb
|
466
469
|
- test/test_score.rb
|
467
470
|
- test/test_signature.rb
|
468
471
|
- test/test_tax.rb
|
data/Procfile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
web: LC_ALL=UTF-8 ./bin/zold node --no-colors --verbose --trace --bind-port=$PORT --port=80 --host=b1.zold.io --threads=0 --invoice=JKFq17yipfjLtX@0000000000000000 --never-reboot
|