stellar-core-backup 0.0.5 → 0.0.7
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/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
|