litestream 0.11.2-x86_64-linux → 0.12.0-x86_64-linux
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +171 -13
- data/lib/litestream/commands.rb +6 -0
- data/lib/litestream/version.rb +1 -1
- data/lib/litestream.rb +8 -4
- data/lib/tasks/litestream_tasks.rake +14 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f2c8d8359a3818741a4a97cc4840cb406cf2d116fc95fe23aadec7b6292b1a0
|
4
|
+
data.tar.gz: 5ee9cd65c126f969a556628b07caf024b7938b48da911f3c2d2076c817c81a2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08acb5e98da7842a3ee74e577aa6bab79eb87a72f15e794774e7e6526793a9eb5e3b917f0a6f8d1ce511f409be8123deac69cab0dd0e37f44c280ac202b6e38f'
|
7
|
+
data.tar.gz: 76f9b61337e208e41dfc29e916d71a4610e0f55f548370541f753a6ca8e8af6b90817dae3902a97cd66440e0c7be55841c21be47a5a304695c014bf848871620
|
data/README.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# litestream-ruby
|
2
2
|
|
3
|
+
<p>
|
4
|
+
<a href="https://rubygems.org/gems/litestream">
|
5
|
+
<img alt="GEM Version" src="https://img.shields.io/gem/v/litestream?color=168AFE&include_prereleases&logo=ruby&logoColor=FE1616">
|
6
|
+
</a>
|
7
|
+
<a href="https://rubygems.org/gems/litestream">
|
8
|
+
<img alt="GEM Downloads" src="https://img.shields.io/gem/dt/litestream?color=168AFE&logo=ruby&logoColor=FE1616">
|
9
|
+
</a>
|
10
|
+
<a href="https://github.com/testdouble/standard">
|
11
|
+
<img alt="Ruby Style" src="https://img.shields.io/badge/style-standard-168AFE?logo=ruby&logoColor=FE1616" />
|
12
|
+
</a>
|
13
|
+
<a href="https://github.com/fractaledmind/litestream-ruby/actions/workflows/main.yml">
|
14
|
+
<img alt="Tests" src="https://github.com/fractaledmind/litestream-ruby/actions/workflows/main.yml/badge.svg" />
|
15
|
+
</a>
|
16
|
+
<a href="https://github.com/sponsors/fractaledmind">
|
17
|
+
<img alt="Sponsors" src="https://img.shields.io/github/sponsors/fractaledmind?color=eb4aaa&logo=GitHub%20Sponsors" />
|
18
|
+
</a>
|
19
|
+
<a href="https://ruby.social/@fractaledmind">
|
20
|
+
<img alt="Ruby.Social Follow" src="https://img.shields.io/mastodon/follow/109291299520066427?domain=https%3A%2F%2Fruby.social&label=%40fractaledmind&style=social">
|
21
|
+
</a>
|
22
|
+
<a href="https://twitter.com/fractaledmind">
|
23
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/url?label=%40fractaledmind&style=social&url=https%3A%2F%2Ftwitter.com%2Ffractaledmind">
|
24
|
+
</a>
|
25
|
+
</p>
|
26
|
+
|
3
27
|
[Litestream](https://litestream.io/) is a standalone streaming replication tool for SQLite. This gem provides a Ruby interface to Litestream.
|
4
28
|
|
5
29
|
## Installation
|
@@ -28,10 +52,10 @@ This gem wraps the standalone executable version of the [Litestream](https://lit
|
|
28
52
|
|
29
53
|
Supported platforms are:
|
30
54
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
55
|
+
- arm64-darwin (macos-arm64)
|
56
|
+
- x86_64-darwin (macos-x64)
|
57
|
+
- arm64-linux (linux-arm64)
|
58
|
+
- x86_64-linux (linux-x64)
|
35
59
|
|
36
60
|
### Using a local installation of `litestream`
|
37
61
|
|
@@ -39,13 +63,13 @@ If you are not able to use the vendored standalone executables (for example, if
|
|
39
63
|
|
40
64
|
For example, if you've installed `litestream` so that the executable is found at `/usr/local/bin/litestream`, then you should set your environment variable like so:
|
41
65
|
|
42
|
-
```
|
66
|
+
```sh
|
43
67
|
LITESTREAM_INSTALL_DIR=/usr/local/bin
|
44
68
|
```
|
45
69
|
|
46
70
|
This also works with relative paths. If you've installed into your app's directory at `./.bin/litestream`:
|
47
71
|
|
48
|
-
```
|
72
|
+
```sh
|
49
73
|
LITESTREAM_INSTALL_DIR=.bin
|
50
74
|
```
|
51
75
|
|
@@ -71,11 +95,12 @@ dbs:
|
|
71
95
|
The gem also provides a default initializer file at `config/initializers/litestream.rb` that allows you to configure these four environment variables referenced in the configuration file in Ruby. By providing a Ruby interface to these environment variables, you can use any method of storing secrets that you prefer. For example, the default generated file uses Rails' encrypted credentials to store your secrets:
|
72
96
|
|
73
97
|
```ruby
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
config.
|
78
|
-
config.
|
98
|
+
Rails.application.configure do
|
99
|
+
litestream_credentials = Rails.application.credentials.litestream
|
100
|
+
|
101
|
+
config.litestream.replica_bucket = litestream_credentials&.replica_bucket
|
102
|
+
config.litestream.replica_key_id = litestream_credentials&.replica_key_id
|
103
|
+
config.litestream.replica_access_key = litestream_credentials&.replica_access_key
|
79
104
|
end
|
80
105
|
```
|
81
106
|
|
@@ -203,6 +228,119 @@ In order to verify that the backup for that database is both restorable and fres
|
|
203
228
|
|
204
229
|
After restoring the backup, the `Litestream.verify!` method will delete the restored database file. If you need the restored database file, use the `litestream:restore` rake task or `Litestream::Commands.restore` method instead.
|
205
230
|
|
231
|
+
### Dashboard
|
232
|
+
|
233
|
+
The gem provides a web dashboard for monitoring the status of your Litestream replication. To mount the dashboard in your Rails application, add the following to your `config/routes.rb` file:
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
authenticate :user, -> (user) { user.admin? } do
|
237
|
+
mount Litestream::Engine, at: "/litestream"
|
238
|
+
end
|
239
|
+
```
|
240
|
+
|
241
|
+
> [!NOTE]
|
242
|
+
> Be sure to [secure the dashboard](#authentication) in production.
|
243
|
+
|
244
|
+
#### Authentication
|
245
|
+
|
246
|
+
Litestream Rails does not restrict access out of the box. You must secure the dashboard yourself. However, it does provide basic HTTP authentication that can be used with basic authentication or Devise. All you need to do is setup a username and password.
|
247
|
+
|
248
|
+
There are two ways to setup a username and password. First, you can use the `LITESTREAM_USERNAME` and `LITESTREAM_PASSWORD` environment variables:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
ENV["LITESTREAM_USERNAME"] = "frodo"
|
252
|
+
ENV["LITESTREAM_PASSWORD"] = "ikeptmysecrets"
|
253
|
+
```
|
254
|
+
|
255
|
+
Second, you can configure the access credentials via the Rails configuration object, under the `litestream` key, in an initializer:
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
# Set authentication credentials for Litestream
|
259
|
+
config.litestream.username = Rails.application.credentials.litestream.username
|
260
|
+
config.litestream.password = Rails.application.credentials.litestream.password
|
261
|
+
```
|
262
|
+
|
263
|
+
Either way, if you have set a username and password, Litestream will use basic HTTP authentication.
|
264
|
+
|
265
|
+
> [!IMPORTANT]
|
266
|
+
> If you have not set a username and password, Litestream will not require any authentication to view the dashboard.
|
267
|
+
|
268
|
+
If you use Devise for authentication in your app, you can also restrict access to the dashboard by using their `authenticate` constraint in your routes file:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
authenticate :user, -> (user) { user.admin? } do
|
272
|
+
mount LitestreamRails::Engine, at: "/litestream"
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
### Examples
|
277
|
+
|
278
|
+
There is only one screen in the dashboard.
|
279
|
+
|
280
|
+
- the show view of the Litestream replication process:
|
281
|
+
|
282
|
+
![screenshot of the single page in the web dashboard, showing details of the Litestream replication process](images/show-screenshot.png)
|
283
|
+
|
284
|
+
### Usage with API-only Applications
|
285
|
+
|
286
|
+
If your Rails application is an API-only application (generated with the `rails new --api` command), you will need to add the following middleware to your `config/application.rb` file in order to use the dashboard UI provided by Litestream:
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
# /config/application.rb
|
290
|
+
config.middleware.use ActionDispatch::Cookies
|
291
|
+
config.middleware.use ActionDispatch::Session::CookieStore
|
292
|
+
config.middleware.use ActionDispatch::Flash
|
293
|
+
```
|
294
|
+
|
295
|
+
### Overwriting the views
|
296
|
+
|
297
|
+
You can find the views in [`app/views`](https://github.com/fractaledmind/litestream/tree/main/app/views).
|
298
|
+
|
299
|
+
```bash
|
300
|
+
app/views/
|
301
|
+
├── layouts
|
302
|
+
│ └── litestream
|
303
|
+
│ ├── _style.html
|
304
|
+
│ └── application.html.erb
|
305
|
+
└── litestream
|
306
|
+
└── processes
|
307
|
+
└── show.html.erb
|
308
|
+
```
|
309
|
+
|
310
|
+
You can always take control of the views by creating your own views and/or partials at these paths in your application. For example, if you wanted to overwrite the application layout, you could create a file at `app/views/layouts/litestream/application.html.erb`. If you wanted to remove the footer and the automatically disappearing flash messages, as one concrete example, you could define that file as:
|
311
|
+
|
312
|
+
```erb
|
313
|
+
<!DOCTYPE html>
|
314
|
+
<html>
|
315
|
+
<head>
|
316
|
+
<title>Litestream</title>
|
317
|
+
<%= csrf_meta_tags %>
|
318
|
+
<%= csp_meta_tag %>
|
319
|
+
|
320
|
+
<%= render "layouts/litestream/style" %>
|
321
|
+
</head>
|
322
|
+
<body class="h-full flex flex-col">
|
323
|
+
<main class="container mx-auto max-w-4xl mt-4 px-2 grow">
|
324
|
+
<%= content_for?(:content) ? yield(:content) : yield %>
|
325
|
+
</main>
|
326
|
+
|
327
|
+
<div class="fixed top-0 left-0 right-0 text-center py-2">
|
328
|
+
<% if notice.present? %>
|
329
|
+
<p class="py-2 px-3 bg-green-50 text-green-500 font-medium rounded-lg inline-block">
|
330
|
+
<%= notice %>
|
331
|
+
</p>
|
332
|
+
<% end %>
|
333
|
+
|
334
|
+
<% if alert.present? %>
|
335
|
+
<p class="py-2 px-3 bg-red-50 text-red-500 font-medium rounded-lg inline-block">
|
336
|
+
<%= alert %>
|
337
|
+
</p>
|
338
|
+
<% end %>
|
339
|
+
</div>
|
340
|
+
</body>
|
341
|
+
</html>
|
342
|
+
```
|
343
|
+
|
206
344
|
### Introspection
|
207
345
|
|
208
346
|
Litestream offers a handful of commands that allow you to introspect the state of your replication. The gem provides a few rake tasks that wrap these commands for you. For example, you can list the databases that Litestream is configured to replicate:
|
@@ -231,7 +369,7 @@ name generation lag start end
|
|
231
369
|
s3 a295b16a796689f3 -156ms 2024-04-17T00:01:19Z 2024-04-17T00:01:19Z
|
232
370
|
```
|
233
371
|
|
234
|
-
|
372
|
+
You can list the snapshots available for a database:
|
235
373
|
|
236
374
|
```shell
|
237
375
|
bin/rails litestream:snapshots -- --database=storage/production.sqlite3
|
@@ -244,6 +382,19 @@ replica generation index size created
|
|
244
382
|
s3 a295b16a796689f3 1 4645465 2024-04-17T00:01:19Z
|
245
383
|
```
|
246
384
|
|
385
|
+
Finally, you can list the wal files available for a database:
|
386
|
+
|
387
|
+
```shell
|
388
|
+
bin/rails litestream:wal -- --database=storage/production.sqlite3
|
389
|
+
```
|
390
|
+
|
391
|
+
This command lists wal files available for that specified database:
|
392
|
+
|
393
|
+
```
|
394
|
+
replica generation index offset size created
|
395
|
+
s3 a295b16a796689f3 1 0 2036 2024-04-17T00:01:19Z
|
396
|
+
```
|
397
|
+
|
247
398
|
### Running commands from Ruby
|
248
399
|
|
249
400
|
In addition to the provided rake tasks, you can also run Litestream commands directly from Ruby. The gem provides a `Litestream::Commands` module that wraps the Litestream CLI commands. This is particularly useful for the introspection commands, as you can use the output in your Ruby code.
|
@@ -269,7 +420,14 @@ Litestream::Commands.snapshots('storage/production.sqlite3')
|
|
269
420
|
# => [{"replica"=>"s3", "generation"=>"5f4341bc3d22d615", "index"=>"0", "size"=>"4645465", "created"=>"2024-04-17T19:48:09Z"}]
|
270
421
|
```
|
271
422
|
|
272
|
-
|
423
|
+
The `Litestream::Commands.wal` method returns an array of hashes with the "replica", "generation", "index", "offset","size", and "created" keys for each wal:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
Litestream::Commands.wal('storage/production.sqlite3')
|
427
|
+
# => [{"replica"=>"s3", "generation"=>"5f4341bc3d22d615", "index"=>"0", "offset"=>"0", "size"=>"2036", "created"=>"2024-04-17T19:48:09Z"}]
|
428
|
+
```
|
429
|
+
|
430
|
+
You can also restore a database programmatically using the `Litestream::Commands.restore` method, which returns the path to the restored database:
|
273
431
|
|
274
432
|
```ruby
|
275
433
|
Litestream::Commands.restore('storage/production.sqlite3')
|
data/lib/litestream/commands.rb
CHANGED
@@ -104,6 +104,12 @@ module Litestream
|
|
104
104
|
execute("snapshots", argv, database, async: async, tabled_output: true)
|
105
105
|
end
|
106
106
|
|
107
|
+
def wal(database, async: false, **argv)
|
108
|
+
raise DatabaseRequiredException, "database argument is required for wal command, e.g. litestream:wal -- --database=path/to/database.sqlite" if database.nil?
|
109
|
+
|
110
|
+
execute("wal", argv, database, async: async, tabled_output: true)
|
111
|
+
end
|
112
|
+
|
107
113
|
private
|
108
114
|
|
109
115
|
def execute(command, argv = {}, database = nil, async: false, tabled_output: false)
|
data/lib/litestream/version.rb
CHANGED
data/lib/litestream.rb
CHANGED
@@ -19,7 +19,7 @@ module Litestream
|
|
19
19
|
|
20
20
|
def self.configure
|
21
21
|
deprecator.warn(
|
22
|
-
|
22
|
+
"Configuring Litestream via Litestream.configure is deprecated. Use Rails.application.configure { config.litestream.* = ... } instead.",
|
23
23
|
caller
|
24
24
|
)
|
25
25
|
self.configuration ||= Configuration.new
|
@@ -33,7 +33,7 @@ module Litestream
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
mattr_writer :username, :password, :queue, :replica_bucket, :replica_key_id, :replica_access_key
|
36
|
+
mattr_writer :username, :password, :queue, :replica_bucket, :replica_key_id, :replica_access_key, :systemctl_command
|
37
37
|
|
38
38
|
class << self
|
39
39
|
def verify!(database_path)
|
@@ -85,10 +85,14 @@ module Litestream
|
|
85
85
|
@@replica_access_key || configuration.replica_access_key
|
86
86
|
end
|
87
87
|
|
88
|
+
def systemctl_command
|
89
|
+
@@systemctl_command || "systemctl status litestream"
|
90
|
+
end
|
91
|
+
|
88
92
|
def replicate_process
|
89
93
|
info = {}
|
90
94
|
if !`which systemctl`.empty?
|
91
|
-
systemctl_status =
|
95
|
+
systemctl_status = `#{Litestream.systemctl_command}`.chomp
|
92
96
|
# ["● litestream.service - Litestream",
|
93
97
|
# " Loaded: loaded (/lib/systemd/system/litestream.service; enabled; vendor preset: enabled)",
|
94
98
|
# " Active: active (running) since Tue 2023-07-25 13:49:43 UTC; 8 months 24 days ago",
|
@@ -115,7 +119,7 @@ module Litestream
|
|
115
119
|
end
|
116
120
|
end
|
117
121
|
else
|
118
|
-
litestream_replicate_ps = `ps -
|
122
|
+
litestream_replicate_ps = `ps -ax | grep litestream | grep replicate`.chomp
|
119
123
|
litestream_replicate_ps.split("\n").each do |line|
|
120
124
|
next unless line.include?("litestream replicate")
|
121
125
|
pid, * = line.split(" ")
|
@@ -75,4 +75,18 @@ namespace :litestream do
|
|
75
75
|
|
76
76
|
Litestream::Commands.snapshots(database, async: true, **options)
|
77
77
|
end
|
78
|
+
|
79
|
+
desc "List all wal files for a database or replica, for example `rake litestream:wal -- -database=storage/production.sqlite3`"
|
80
|
+
task wal: :environment do
|
81
|
+
options = {}
|
82
|
+
if (separator_index = ARGV.index("--"))
|
83
|
+
ARGV.slice(separator_index + 1, ARGV.length)
|
84
|
+
.map { |pair| pair.split("=") }
|
85
|
+
.each { |opt| options[opt[0]] = opt[1] || nil }
|
86
|
+
end
|
87
|
+
database = options.delete("--database") || options.delete("-database")
|
88
|
+
options.symbolize_keys!
|
89
|
+
|
90
|
+
Litestream::Commands.wal(database, async: true, **options)
|
91
|
+
end
|
78
92
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: litestream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: x86_64-linux
|
6
6
|
authors:
|
7
7
|
- Stephen Margheim
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logfmt
|
@@ -205,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '0'
|
207
207
|
requirements: []
|
208
|
-
rubygems_version: 3.5.
|
208
|
+
rubygems_version: 3.5.21
|
209
209
|
signing_key:
|
210
210
|
specification_version: 4
|
211
211
|
summary: Integrate Litestream with the RubyGems infrastructure.
|