stellar-core-backup 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/config/sample.yaml +1 -0
- data/lib/stellar-core-backup/job.rb +39 -6
- data/lib/stellar-core-backup/utils.rb +60 -0
- data/lib/stellar-core-backup/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c708f769686ce12524217fe911479cfe10aab8f
|
4
|
+
data.tar.gz: 9ffb182e1def72ef33cd6fba0b6e9c68289cd47b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49df44ceefb82383d46c86cf2b70275ce029990109f6fdff67a595218f970d5794d922f4e680c9c3d70d63a7594d53e6091e351482149d351bc0948d420a2af1
|
7
|
+
data.tar.gz: 60abb9dbbac3ae53955cdf96f5006c6b71d98c037e138f8f4586c58d6652f30d33c764221d67fcb20344abaec541d01431c446009a4cbe826936a9b8ca5c5bc5
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ We are using SKS Keyservers for public key distribution available at hkp://pool.
|
|
29
29
|
|s3_bucket| S3 bucket to store/retrieve buckets to/from|
|
30
30
|
|s3_path| S3 Path prefix, can be used for backing up multiple core nodes to the same bucket|
|
31
31
|
|gpg_key| GPG key ID used for signing and verification of the stellar-core backups. The provided ID is the Stellar public key|
|
32
|
+
|pushgateway_url| Optional prometheus pushgateway URL to publish metrics to|
|
32
33
|
|
33
34
|
## Usage As Command Line Tool
|
34
35
|
|
data/config/sample.yaml
CHANGED
@@ -17,23 +17,26 @@ module StellarCoreBackup
|
|
17
17
|
@listlen = args[:listlen]
|
18
18
|
|
19
19
|
# Set common run time parameters
|
20
|
-
@job_type
|
21
|
-
@gpg_key
|
22
|
-
@working_dir
|
23
|
-
@cmd
|
24
|
-
@select
|
25
|
-
@s3
|
20
|
+
@job_type = args[:type]
|
21
|
+
@gpg_key = @config.get('gpg_key')
|
22
|
+
@working_dir = StellarCoreBackup::Utils.create_working_dir(@config.get('working_dir'))
|
23
|
+
@cmd = StellarCoreBackup::Cmd.new(@working_dir)
|
24
|
+
@select = args[:select] if args.has_key?(:select)
|
25
|
+
@s3 = StellarCoreBackup::S3.new(@config)
|
26
|
+
@pushgateway_url = @config.get('pushgateway_url')
|
26
27
|
|
27
28
|
# Set per operation type run time parameters
|
28
29
|
if args.has_key?(:type) then
|
29
30
|
case args[:type]
|
30
31
|
when 'backup'
|
31
32
|
puts 'info: backing up stellar-core'
|
33
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_start_time')
|
32
34
|
@backup_dir = StellarCoreBackup::Utils.create_backup_dir(@config.get('backup_dir'))
|
33
35
|
@db = StellarCoreBackup::Database.new(@config)
|
34
36
|
@fs = StellarCoreBackup::Filesystem.new(@config)
|
35
37
|
when 'restore'
|
36
38
|
puts 'info: restoring stellar-core'
|
39
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_start_time')
|
37
40
|
@db_restore = StellarCoreBackup::Restore::Database.new(@config)
|
38
41
|
@fs_restore = StellarCoreBackup::Restore::Filesystem.new(@config)
|
39
42
|
@utils = StellarCoreBackup::Utils.new(@config)
|
@@ -70,14 +73,23 @@ module StellarCoreBackup
|
|
70
73
|
end
|
71
74
|
when 'backup'
|
72
75
|
begin
|
76
|
+
if !StellarCoreBackup::Utils.core_healthy?(@config) then
|
77
|
+
puts "error: Can't back up unhealthy stellar-core"
|
78
|
+
raise StandardError
|
79
|
+
end
|
73
80
|
puts 'info: stopping stellar-core'
|
74
81
|
# using sudo, if running as non root uid then you will need to configure sudoers
|
75
82
|
stop_core = @cmd.run_and_capture('sudo', ['/bin/systemctl', 'stop', 'stellar-core'])
|
76
83
|
# only proceed if core is stopped
|
77
84
|
if stop_core.success then
|
85
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_db_dump_start_time')
|
78
86
|
@db.backup
|
87
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_db_dump_finish_time')
|
88
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_fs_backup_start_time')
|
79
89
|
@fs.backup
|
90
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_fs_backup_finish_time')
|
80
91
|
if @verify then
|
92
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_verify_start_time')
|
81
93
|
create_hash_file = @cmd.run_and_capture('find', ['.', '-type', 'f', '!', '-name', 'SHA256SUMS', '|', 'xargs', 'sha256sum', '>', 'SHA256SUMS'])
|
82
94
|
if create_hash_file.success then
|
83
95
|
puts "info: sha sums file created"
|
@@ -88,14 +100,19 @@ module StellarCoreBackup
|
|
88
100
|
sign_hash_file = @cmd.run_and_capture('gpg', ['--local-user', @gpg_key, '--detach-sign', 'SHA256SUMS'])
|
89
101
|
if sign_hash_file.success then
|
90
102
|
puts "info: gpg signature created ok"
|
103
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_verify_finish_time')
|
91
104
|
else
|
92
105
|
puts 'error: error signing sha256sum file'
|
93
106
|
raise StandardError
|
94
107
|
end
|
95
108
|
end
|
96
109
|
# create tar archive with fs, db backup files and if requested the file of shas256sums and corresponding gpg signature.
|
110
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_tar_start_time')
|
97
111
|
@backup = StellarCoreBackup::Utils.create_backup_tar(@working_dir, @backup_dir)
|
112
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_tar_finish_time')
|
113
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_s3_push_start_time')
|
98
114
|
@s3.push(@backup)
|
115
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_s3_push_finish_time')
|
99
116
|
else
|
100
117
|
puts 'error: can not stop stellar-core'
|
101
118
|
raise StandardError
|
@@ -118,6 +135,9 @@ module StellarCoreBackup
|
|
118
135
|
puts e
|
119
136
|
# clean up working_dir
|
120
137
|
StellarCoreBackup::Utils.cleanup(@working_dir)
|
138
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_fail_time')
|
139
|
+
else
|
140
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_backup_success_time')
|
121
141
|
end
|
122
142
|
when 'restore'
|
123
143
|
begin
|
@@ -133,9 +153,14 @@ module StellarCoreBackup
|
|
133
153
|
# if no manual selection has been made, use the latest as derived from the s3.latest method
|
134
154
|
# this method returns an array so set @select to the first and only element
|
135
155
|
@select=@s3.latest(1)[0] if ! @select
|
156
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_s3_get_start_time')
|
136
157
|
@backup_archive = @s3.get(@select)
|
158
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_s3_get_finish_time')
|
159
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_untar_start_time')
|
137
160
|
@utils.extract_backup(@backup_archive)
|
161
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_untar_finish_time')
|
138
162
|
if @verify then
|
163
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_verify_start_time')
|
139
164
|
verify_hash_file = @cmd.run_and_capture('gpg', ['--local-user', @gpg_key, '--verify', 'SHA256SUMS.sig', 'SHA256SUMS', '2>&1'])
|
140
165
|
if verify_hash_file.success then
|
141
166
|
puts "info: gpg signature processed ok"
|
@@ -152,14 +177,19 @@ module StellarCoreBackup
|
|
152
177
|
end
|
153
178
|
if StellarCoreBackup::Utils.confirm_shasums_definitive(@working_dir, @backup_archive) then
|
154
179
|
puts 'info: SHA256SUMS file list matches delivered archive'
|
180
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_verify_finish_time')
|
155
181
|
else
|
156
182
|
puts 'error: unknown additional file(s) detected in archive'
|
157
183
|
raise StandardError
|
158
184
|
end
|
159
185
|
end
|
160
186
|
StellarCoreBackup::Utils.cleanbucket(@fs_restore.core_data_dir) if @clean
|
187
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_fs_restore_start_time')
|
161
188
|
@fs_restore.restore(@backup_archive)
|
189
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_fs_restore_finish_time')
|
190
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_db_restore_start_time')
|
162
191
|
@db_restore.restore()
|
192
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_db_restore_finish_time')
|
163
193
|
|
164
194
|
# restart stellar-core post restore
|
165
195
|
puts 'info: starting stellar-core'
|
@@ -182,6 +212,9 @@ module StellarCoreBackup
|
|
182
212
|
puts e
|
183
213
|
# clean up working_dir
|
184
214
|
StellarCoreBackup::Utils.cleanup(@working_dir)
|
215
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_fail_time')
|
216
|
+
else
|
217
|
+
StellarCoreBackup::Utils.push_metric(@pushgateway_url, 'stellar_core_restore_success_time')
|
185
218
|
end
|
186
219
|
end
|
187
220
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
require 'time'
|
5
|
+
|
2
6
|
|
3
7
|
module StellarCoreBackup
|
4
8
|
class Utils
|
@@ -133,5 +137,61 @@ module StellarCoreBackup
|
|
133
137
|
return Etc.nprocessors
|
134
138
|
end
|
135
139
|
|
140
|
+
# check stellar-core status
|
141
|
+
Contract StellarCoreBackup::Config => Bool
|
142
|
+
def self.core_healthy?(config)
|
143
|
+
port = get_admin_port(config.get('core_config'))
|
144
|
+
url = "http://127.0.0.1:%s/info" % port
|
145
|
+
uri = URI(url)
|
146
|
+
begin
|
147
|
+
response = Net::HTTP.get(uri)
|
148
|
+
state = JSON.parse(response)['info']['state']
|
149
|
+
if state == 'Synced!' then
|
150
|
+
puts "info: stellar-core up and synced"
|
151
|
+
return true
|
152
|
+
else
|
153
|
+
puts "error: stellar-core status is: %s" % state
|
154
|
+
return false
|
155
|
+
end
|
156
|
+
rescue
|
157
|
+
puts "info: stellar-core down or not synced"
|
158
|
+
return false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
Contract String => String
|
164
|
+
def self.get_admin_port(config)
|
165
|
+
File.open(config,'r') do |fd|
|
166
|
+
fd.each_line do |line|
|
167
|
+
if (line[/^HTTP_PORT=/]) then
|
168
|
+
port = /^HTTP_PORT=(.*)/.match(line).captures[0]
|
169
|
+
return port
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Publishes metric to pushgateway
|
176
|
+
# if no value provided current epoch timestamp will be used
|
177
|
+
Contract Any, String, Any => Bool
|
178
|
+
def self.push_metric(url, metric, value=nil)
|
179
|
+
if url.nil? then
|
180
|
+
# No url means pushgateway URL is not configured
|
181
|
+
return false
|
182
|
+
end
|
183
|
+
|
184
|
+
if value.nil? then
|
185
|
+
value = Time.now.to_i
|
186
|
+
end
|
187
|
+
|
188
|
+
uri = URI(url)
|
189
|
+
req = Net::HTTP::Post.new(uri.request_uri)
|
190
|
+
req.body = "%s %i\n" % [metric, value]
|
191
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
192
|
+
http.request(req)
|
193
|
+
return true
|
194
|
+
end
|
195
|
+
|
136
196
|
end
|
137
197
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stellar-core-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Llewellyn-Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: contracts
|