kamal-backup 0.3.0.beta6 → 0.3.0.beta8
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/lib/kamal_backup/cli.rb +10 -5
- data/lib/kamal_backup/command.rb +96 -12
- data/lib/kamal_backup/kamal_bridge.rb +16 -1
- data/lib/kamal_backup/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d920c58d8ff83794df465f0549d8599ea6a5e815b800221fa850ce024241abfa
|
|
4
|
+
data.tar.gz: feb8374a19862349d1fb0b3d55e3e697b45df66d58fc0c0f63ddba4767ed01f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e36489f2557dca0695be87b779a9b20f96148b141e67a9422bc8933c925ea68a17a73d221c56f4a51585258194752f0db4f0b6fed4a4845783334e6dc0d8e0e
|
|
7
|
+
data.tar.gz: f8bb63eb69f7da8bdfcc001e07c95495ac60fa6996eb4b4188cfb2a8bc453979176985703f897c8e5ac4a9b02faec5cf3d76aad15862b0c964d6c961c2910556
|
data/lib/kamal_backup/cli.rb
CHANGED
|
@@ -129,11 +129,13 @@ module KamalBackup
|
|
|
129
129
|
|
|
130
130
|
def print_remote_version_status
|
|
131
131
|
status = remote_version == VERSION ? "in sync" : "out of sync"
|
|
132
|
+
status_color = status == "in sync" ? :green : :red
|
|
133
|
+
status_output = CommandOutput.new(io: $stdout, env: command_env)
|
|
132
134
|
|
|
133
135
|
puts("local: #{VERSION}")
|
|
134
136
|
puts("remote: #{remote_version}")
|
|
135
|
-
puts("status: #{status}")
|
|
136
|
-
puts("fix: #{accessory_reboot_command}") if status == "out of sync"
|
|
137
|
+
puts("status: #{status_output.decorate(status, status_color, :bold)}")
|
|
138
|
+
puts("fix: #{status_output.decorate(accessory_reboot_command, :yellow, :bold)}") if status == "out of sync"
|
|
137
139
|
end
|
|
138
140
|
|
|
139
141
|
def validate_deploy_config
|
|
@@ -399,14 +401,17 @@ module KamalBackup
|
|
|
399
401
|
|
|
400
402
|
def self.start(argv = ARGV, env: ENV)
|
|
401
403
|
self.command_env = env
|
|
402
|
-
|
|
404
|
+
output = CommandOutput.new(io: $stderr, env: env)
|
|
405
|
+
Command.with_output(output) do
|
|
403
406
|
super(normalize_global_options(argv))
|
|
404
407
|
end
|
|
405
408
|
rescue Error => e
|
|
406
|
-
|
|
409
|
+
output ||= CommandOutput.new(io: $stderr, env: env)
|
|
410
|
+
output.error("(#{e.class}): #{e.message}", redactor: Redactor.new(env: env))
|
|
407
411
|
exit(1)
|
|
408
412
|
rescue Interrupt
|
|
409
|
-
|
|
413
|
+
output ||= CommandOutput.new(io: $stderr, env: env)
|
|
414
|
+
output.error("(Interrupt): interrupted", redactor: Redactor.new(env: env))
|
|
410
415
|
exit(130)
|
|
411
416
|
ensure
|
|
412
417
|
self.command_env = nil
|
data/lib/kamal_backup/command.rb
CHANGED
|
@@ -27,14 +27,57 @@ module KamalBackup
|
|
|
27
27
|
CommandResult = Struct.new(:stdout, :stderr, :status, :streamed, keyword_init: true)
|
|
28
28
|
|
|
29
29
|
class CommandOutput
|
|
30
|
-
|
|
30
|
+
LEVELS = {
|
|
31
|
+
"DEBUG" => 0,
|
|
32
|
+
"INFO" => 1,
|
|
33
|
+
"WARN" => 2,
|
|
34
|
+
"ERROR" => 3,
|
|
35
|
+
"FATAL" => 4
|
|
36
|
+
}.freeze
|
|
37
|
+
LEVEL_COLORS = {
|
|
38
|
+
"DEBUG" => :black,
|
|
39
|
+
"INFO" => :blue,
|
|
40
|
+
"WARN" => :yellow,
|
|
41
|
+
"ERROR" => :red,
|
|
42
|
+
"FATAL" => :red
|
|
43
|
+
}.freeze
|
|
44
|
+
COLOR_CODES = {
|
|
45
|
+
black: 30,
|
|
46
|
+
red: 31,
|
|
47
|
+
green: 32,
|
|
48
|
+
yellow: 33,
|
|
49
|
+
blue: 34,
|
|
50
|
+
magenta: 35,
|
|
51
|
+
cyan: 36,
|
|
52
|
+
white: 37,
|
|
53
|
+
light_black: 90,
|
|
54
|
+
light_red: 91,
|
|
55
|
+
light_green: 92,
|
|
56
|
+
light_yellow: 93,
|
|
57
|
+
light_blue: 94,
|
|
58
|
+
light_magenta: 95,
|
|
59
|
+
light_cyan: 96,
|
|
60
|
+
light_white: 97
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
63
|
+
def initialize(io: $stdout, env: ENV, verbosity: :info)
|
|
31
64
|
@io = io
|
|
65
|
+
@env = env
|
|
66
|
+
@verbosity = LEVELS.fetch(verbosity.to_s.upcase)
|
|
32
67
|
@mutex = Mutex.new
|
|
33
68
|
@buffers = {}
|
|
34
69
|
end
|
|
35
70
|
|
|
36
71
|
def info(message, redactor:)
|
|
37
|
-
|
|
72
|
+
write_message("INFO", redactor.redact_string(message))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def error(message, redactor:)
|
|
76
|
+
write_message("ERROR", colorize(redactor.redact_string(message), :red, :bold))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def decorate(value, color, mode = nil)
|
|
80
|
+
colorize(value, color, mode)
|
|
38
81
|
end
|
|
39
82
|
|
|
40
83
|
def command_start(spec, redactor:)
|
|
@@ -42,8 +85,8 @@ module KamalBackup
|
|
|
42
85
|
started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
43
86
|
display = spec.display(redactor)
|
|
44
87
|
|
|
45
|
-
|
|
46
|
-
|
|
88
|
+
write_message("INFO", "Running #{colorize(display, :yellow, :bold)} #{local_target}", id)
|
|
89
|
+
write_message("DEBUG", "Command: #{colorize(display, :blue)}", id)
|
|
47
90
|
|
|
48
91
|
{ id: id, started_at: started_at, redactor: redactor }
|
|
49
92
|
end
|
|
@@ -51,6 +94,7 @@ module KamalBackup
|
|
|
51
94
|
def command_output(context, _stream, data, redactor:)
|
|
52
95
|
raw = data.to_s
|
|
53
96
|
return if raw.empty?
|
|
97
|
+
return unless log_level?("DEBUG")
|
|
54
98
|
|
|
55
99
|
synchronize do
|
|
56
100
|
key = [context.fetch(:id), _stream]
|
|
@@ -62,16 +106,23 @@ module KamalBackup
|
|
|
62
106
|
def command_exit(context, status)
|
|
63
107
|
runtime = Process.clock_gettime(Process::CLOCK_MONOTONIC) - context.fetch(:started_at)
|
|
64
108
|
result = status.to_i.zero? ? "successful" : "failed"
|
|
109
|
+
result_color = status.to_i.zero? ? :green : :red
|
|
65
110
|
|
|
66
111
|
synchronize do
|
|
67
112
|
flush_output_buffers(context)
|
|
68
|
-
|
|
113
|
+
write_message_unlocked("INFO", "Finished in #{format("%.3f seconds", runtime)} with exit status #{status} (#{colorize(result, result_color, :bold)}).", context.fetch(:id))
|
|
69
114
|
end
|
|
70
115
|
end
|
|
71
116
|
|
|
72
117
|
private
|
|
73
|
-
def
|
|
74
|
-
|
|
118
|
+
def write_message(level, message, id = nil)
|
|
119
|
+
return unless log_level?(level)
|
|
120
|
+
|
|
121
|
+
synchronize { write_message_unlocked(level, message, id) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def write_message_unlocked(level, message, id = nil)
|
|
125
|
+
@io.puts(format_message(level, message, id)) if log_level?(level)
|
|
75
126
|
end
|
|
76
127
|
|
|
77
128
|
def synchronize(&block)
|
|
@@ -87,7 +138,7 @@ module KamalBackup
|
|
|
87
138
|
end
|
|
88
139
|
|
|
89
140
|
@buffers[key] = buffer
|
|
90
|
-
write_output(context, output, redactor: redactor) unless output.empty?
|
|
141
|
+
write_output(context, output, redactor: redactor, stream: key.last) unless output.empty?
|
|
91
142
|
end
|
|
92
143
|
|
|
93
144
|
def flush_output_buffers(context)
|
|
@@ -98,17 +149,50 @@ module KamalBackup
|
|
|
98
149
|
output = @buffers.delete(key)
|
|
99
150
|
next if output.to_s.empty?
|
|
100
151
|
|
|
101
|
-
write_output(context, output, redactor: context.fetch(:redactor))
|
|
102
|
-
@io.puts unless output.end_with?("\n")
|
|
152
|
+
write_output(context, output, redactor: context.fetch(:redactor), stream: key.last)
|
|
103
153
|
end
|
|
104
154
|
end
|
|
105
155
|
|
|
106
|
-
def write_output(context, output, redactor:)
|
|
156
|
+
def write_output(context, output, redactor:, stream: nil)
|
|
157
|
+
color = stream == :stderr ? :red : :green
|
|
158
|
+
|
|
107
159
|
redactor.redact_string(output).each_line do |line|
|
|
108
|
-
|
|
160
|
+
write_message_unlocked("DEBUG", colorize("\t#{line}".chomp, color), context.fetch(:id))
|
|
109
161
|
end
|
|
110
162
|
@io.flush if @io.respond_to?(:flush)
|
|
111
163
|
end
|
|
164
|
+
|
|
165
|
+
def format_message(level, message, id = nil)
|
|
166
|
+
message = "[#{colorize(id, :green)}] #{message}" if id
|
|
167
|
+
"#{colorize(level.rjust(6), LEVEL_COLORS.fetch(level))} #{message}"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def local_target
|
|
171
|
+
user = @env["USER"].to_s.empty? ? @env["USERNAME"].to_s : @env["USER"].to_s
|
|
172
|
+
|
|
173
|
+
if user.empty?
|
|
174
|
+
"on #{colorize("localhost", :blue)}"
|
|
175
|
+
else
|
|
176
|
+
"as #{colorize(user, :blue)}@#{colorize("localhost", :blue)}"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def log_level?(level)
|
|
181
|
+
LEVELS.fetch(level) >= @verbosity
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def colorize(value, color, mode = nil)
|
|
185
|
+
string = value.to_s
|
|
186
|
+
return string unless colorize?
|
|
187
|
+
return string unless COLOR_CODES.key?(color)
|
|
188
|
+
|
|
189
|
+
prefix = mode == :bold ? "\e[1;" : "\e[0;"
|
|
190
|
+
"#{prefix}#{COLOR_CODES.fetch(color)};49m#{string}\e[0m"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def colorize?
|
|
194
|
+
@env["SSHKIT_COLOR"] || (@io.respond_to?(:tty?) && @io.tty?)
|
|
195
|
+
end
|
|
112
196
|
end
|
|
113
197
|
|
|
114
198
|
class Command
|
|
@@ -215,9 +215,10 @@ module KamalBackup
|
|
|
215
215
|
end
|
|
216
216
|
|
|
217
217
|
def capture_kamal(argv, stream: false)
|
|
218
|
-
spec = CommandSpec.new(argv: argv)
|
|
218
|
+
spec = CommandSpec.new(argv: argv, env: kamal_stream_env(stream))
|
|
219
219
|
options = {
|
|
220
220
|
redactor: @redactor,
|
|
221
|
+
log: !stream,
|
|
221
222
|
log_output: false,
|
|
222
223
|
tee_stdout: stream ? @stdout : nil,
|
|
223
224
|
tee_stderr: stream ? @stderr : nil
|
|
@@ -230,6 +231,20 @@ module KamalBackup
|
|
|
230
231
|
end
|
|
231
232
|
end
|
|
232
233
|
|
|
234
|
+
def kamal_stream_env(stream)
|
|
235
|
+
return {} unless stream
|
|
236
|
+
|
|
237
|
+
if @env["SSHKIT_COLOR"].to_s.empty?
|
|
238
|
+
stream_color? ? { "SSHKIT_COLOR" => "1" } : {}
|
|
239
|
+
else
|
|
240
|
+
{ "SSHKIT_COLOR" => @env["SSHKIT_COLOR"] }
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def stream_color?
|
|
245
|
+
[@stdout, @stderr].any? { |io| io.respond_to?(:tty?) && io.tty? }
|
|
246
|
+
end
|
|
247
|
+
|
|
233
248
|
def parse_version_line(output)
|
|
234
249
|
output.to_s.lines.map(&:strip).reverse.find { |line| line.match?(VERSION_LINE_PATTERN) }.to_s
|
|
235
250
|
end
|
data/lib/kamal_backup/version.rb
CHANGED