litestream 0.3.3-x86_64-linux → 0.4.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 +91 -6
- data/exe/litestream +0 -1
- data/lib/litestream/commands.rb +33 -10
- data/lib/litestream/generators/litestream/install_generator.rb +11 -1
- data/lib/litestream/generators/litestream/templates/{config.yml → config.yml.erb} +6 -2
- data/lib/litestream/generators/litestream/templates/initializer.rb +9 -14
- data/lib/litestream/version.rb +1 -1
- data/lib/litestream.rb +1 -2
- data/lib/tasks/litestream_tasks.rake +14 -3
- 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: 296b0fda9f7f9cfce9f44369d76170a5a2437ecd26ea976f668f4e6ac9ccf4da
|
4
|
+
data.tar.gz: 8e18eb8bf7b9cd21e54e98cd00096129146f38d949f4c51c5b7cee34aebbc93f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75bab85fa75e5199110b20276b983bdaf404d8696792f83e53d9a06fee1a6cd155c2363ed51b4c8b0c101b45a2d0aaa83a29a18bb06cba31de2428cac4f58336
|
7
|
+
data.tar.gz: f51dbe2cd1c998f834f825cff2749fbbaee824efd9b4339013d753c7d20bb6f4ffca38873f0d7172913afbb9b038a1f049d91fecacde9ee8627ca8bd328d33cf
|
data/README.md
CHANGED
@@ -49,13 +49,13 @@ LITESTREAM_INSTALL_DIR=.bin
|
|
49
49
|
|
50
50
|
You configure the Litestream executable through the [`config/litestream.yml` file](https://litestream.io/reference/config/), which is a standard Litestream configuration file as if Litestream was running in a traditional installation.
|
51
51
|
|
52
|
-
The gem streamlines the configuration process by providing a default configuration file for you. This configuration file will backup
|
52
|
+
The gem streamlines the configuration process by providing a default configuration file for you. This configuration file will backup all SQLite databases defined in your `config/database.yml` file to one replication bucket. In order to ensure that no secrets are stored in plain-text in your repository, this configuration file leverages Litestream's support for environment variables. The default configuration file looks like this if you only have one SQLite database:
|
53
53
|
|
54
54
|
```yaml
|
55
55
|
dbs:
|
56
56
|
- path: $LITESTREAM_DATABASE_PATH
|
57
57
|
replicas:
|
58
|
-
- url: $
|
58
|
+
- url: $LITESTREAM_REPLICA_BUCKET
|
59
59
|
access-key-id: $LITESTREAM_ACCESS_KEY_ID
|
60
60
|
secret-access-key: $LITESTREAM_SECRET_ACCESS_KEY
|
61
61
|
```
|
@@ -66,7 +66,7 @@ The gem also provides a default initializer file at `config/initializers/litestr
|
|
66
66
|
litestream_credentials = Rails.application.credentials.litestream
|
67
67
|
Litestream.configure do |config|
|
68
68
|
config.database_path = ActiveRecord::Base.connection_db_config.database
|
69
|
-
config.
|
69
|
+
config.replica_bucket = litestream_credentials.replica_bucket
|
70
70
|
config.replica_key_id = litestream_credentials.replica_key_id
|
71
71
|
config.replica_access_key = litestream_credentials.replica_access_key
|
72
72
|
end
|
@@ -92,9 +92,94 @@ bin/rails litestream:replicate -- -exec "foreman start"
|
|
92
92
|
|
93
93
|
This example utilizes the `-exec` option available on [the `replicate` command](https://litestream.io/reference/replicate/) which provides basic process management, since Litestream will exit when the child process exits. In this example, we only launch our collection of Rails application processes (like Rails and SolidQueue, for example) after the Litestream replication process is ready.
|
94
94
|
|
95
|
-
The
|
95
|
+
The Litestream `replicate` command supports the following options, which can be passed through the rake task:
|
96
|
+
```shell
|
97
|
+
-config PATH
|
98
|
+
Specifies the configuration file.
|
99
|
+
Defaults to /etc/litestream.yml
|
100
|
+
|
101
|
+
-exec CMD
|
102
|
+
Executes a subcommand. Litestream will exit when the child
|
103
|
+
process exits. Useful for simple process management.
|
104
|
+
|
105
|
+
-no-expand-env
|
106
|
+
Disables environment variable expansion in configuration file.
|
107
|
+
```
|
108
|
+
|
109
|
+
### Restoration
|
96
110
|
|
97
|
-
|
111
|
+
You can restore any replicated database at any point using the gem's provided `litestream:restore` rake task. This rake task requires that you specify which specific database you want to restore. As with the `litestream:replicate` task, you pass arguments to the rake task via argument forwarding. For example, to restore the production database, you would run:
|
112
|
+
|
113
|
+
```shell
|
114
|
+
bin/rails litestream:restore -- --database=storage/production.sqlite3
|
115
|
+
# or
|
116
|
+
bundle exec rake litestream:restore -- --database=storage/production.sqlite3
|
117
|
+
```
|
118
|
+
|
119
|
+
You can restore any of the databases specified in your `config/litestream.yml` file. The `--database` argument should be the path to the database file you want to restore and must match the value for the `path` key of one of your configured databases. The `litestream:restore` rake task will automatically load the configuration file and set the environment variables before calling the Litestream executable.
|
120
|
+
|
121
|
+
If you need to pass arguments through the rake task to the underlying `litestream` command, that can be done with additional forwarded arguments:
|
122
|
+
|
123
|
+
```shell
|
124
|
+
bin/rails litestream:replicate -- --database=storage/production.sqlite3 --if-db-not-exists
|
125
|
+
```
|
126
|
+
|
127
|
+
You can forward arguments in whatever order you like, you simply need to ensure that the `--database` argument is present. You can also use either a single-dash `-database` or double-dash `--database` argument format. The Litestream `restore` command supports the following options, which can be passed through the rake task:
|
128
|
+
|
129
|
+
```shell
|
130
|
+
-o PATH
|
131
|
+
Output path of the restored database.
|
132
|
+
Defaults to original DB path.
|
133
|
+
|
134
|
+
-if-db-not-exists
|
135
|
+
Returns exit code of 0 if the database already exists.
|
136
|
+
|
137
|
+
-if-replica-exists
|
138
|
+
Returns exit code of 0 if no backups found.
|
139
|
+
|
140
|
+
-parallelism NUM
|
141
|
+
Determines the number of WAL files downloaded in parallel.
|
142
|
+
Defaults to 8
|
143
|
+
|
144
|
+
-replica NAME
|
145
|
+
Restore from a specific replica.
|
146
|
+
Defaults to replica with latest data.
|
147
|
+
|
148
|
+
-generation NAME
|
149
|
+
Restore from a specific generation.
|
150
|
+
Defaults to generation with latest data.
|
151
|
+
|
152
|
+
-index NUM
|
153
|
+
Restore up to a specific WAL index (inclusive).
|
154
|
+
Defaults to use the highest available index.
|
155
|
+
|
156
|
+
-timestamp TIMESTAMP
|
157
|
+
Restore to a specific point-in-time.
|
158
|
+
Defaults to use the latest available backup.
|
159
|
+
|
160
|
+
-config PATH
|
161
|
+
Specifies the configuration file.
|
162
|
+
Defaults to /etc/litestream.yml
|
163
|
+
|
164
|
+
-no-expand-env
|
165
|
+
Disables environment variable expansion in configuration file.
|
166
|
+
```
|
167
|
+
|
168
|
+
### Additional commands
|
169
|
+
|
170
|
+
The rake tasks are the recommended way to interact with the Litestream utility in your Rails application or Ruby project. But, you _can_ work directly with the Litestream CLI. Since the gem installs the native executable via Bundler, the `litestream` command will be available in your `PATH`.
|
171
|
+
|
172
|
+
The full set of commands available to the `litestream` executable are covered in Litestream's [command reference](https://litestream.io/reference/), but can be summarized as:
|
173
|
+
|
174
|
+
```shell
|
175
|
+
litestream databases [arguments]
|
176
|
+
litestream generations [arguments] DB_PATH|REPLICA_URL
|
177
|
+
litestream replicate [arguments]
|
178
|
+
litestream restore [arguments] DB_PATH|REPLICA_URL
|
179
|
+
litestream snapshots [arguments] DB_PATH|REPLICA_URL
|
180
|
+
litestream version
|
181
|
+
litestream wal [arguments] DB_PATH|REPLICA_URL
|
182
|
+
```
|
98
183
|
|
99
184
|
### Using in development
|
100
185
|
|
@@ -113,7 +198,7 @@ Once you have a MinIO server running, you can create a bucket for Litestream to
|
|
113
198
|
```ruby
|
114
199
|
Litestream.configure do |config|
|
115
200
|
config.database_path = ActiveRecord::Base.connection_db_config.database
|
116
|
-
config.
|
201
|
+
config.replica_bucket = "s3://mybkt.localhost:9000/"
|
117
202
|
config.replica_key_id = "minioadmin"
|
118
203
|
config.replica_access_key = "minioadmin"
|
119
204
|
end
|
data/exe/litestream
CHANGED
@@ -5,7 +5,6 @@ require "litestream/commands"
|
|
5
5
|
|
6
6
|
begin
|
7
7
|
command = [Litestream::Commands.executable, *ARGV]
|
8
|
-
puts command.inspect
|
9
8
|
exec(*command)
|
10
9
|
rescue Litestream::Commands::UnsupportedPlatformException, Litestream::Commands::ExecutableNotFoundException => e
|
11
10
|
warn("ERROR: " + e.message)
|
data/lib/litestream/commands.rb
CHANGED
@@ -6,16 +6,13 @@ module Litestream
|
|
6
6
|
GEM_NAME = "litestream"
|
7
7
|
|
8
8
|
# raised when the host platform is not supported by upstream litestream's binary releases
|
9
|
-
|
10
|
-
end
|
9
|
+
UnsupportedPlatformException = Class.new(StandardError)
|
11
10
|
|
12
11
|
# raised when the litestream executable could not be found where we expected it to be
|
13
|
-
|
14
|
-
end
|
12
|
+
ExecutableNotFoundException = Class.new(StandardError)
|
15
13
|
|
16
14
|
# raised when LITESTREAM_INSTALL_DIR does not exist
|
17
|
-
|
18
|
-
end
|
15
|
+
DirectoryNotFoundException = Class.new(StandardError)
|
19
16
|
|
20
17
|
def self.platform
|
21
18
|
[:cpu, :os].map { |m| Gem::Platform.local.send(m) }.join("-")
|
@@ -74,10 +71,9 @@ module Litestream
|
|
74
71
|
|
75
72
|
def self.replicate(argv = {})
|
76
73
|
if Litestream.configuration
|
77
|
-
ENV["
|
78
|
-
ENV["
|
79
|
-
ENV["
|
80
|
-
ENV["LITESTREAM_SECRET_ACCESS_KEY"] = Litestream.configuration.replica_access_key
|
74
|
+
ENV["LITESTREAM_REPLICA_BUCKET"] ||= Litestream.configuration.replica_bucket
|
75
|
+
ENV["LITESTREAM_ACCESS_KEY_ID"] ||= Litestream.configuration.replica_key_id
|
76
|
+
ENV["LITESTREAM_SECRET_ACCESS_KEY"] ||= Litestream.configuration.replica_access_key
|
81
77
|
end
|
82
78
|
|
83
79
|
args = {
|
@@ -93,5 +89,32 @@ module Litestream
|
|
93
89
|
exec(*command)
|
94
90
|
end
|
95
91
|
end
|
92
|
+
|
93
|
+
def self.restore(database, argv = {})
|
94
|
+
if Litestream.configuration
|
95
|
+
ENV["LITESTREAM_REPLICA_BUCKET"] ||= Litestream.configuration.replica_bucket
|
96
|
+
ENV["LITESTREAM_ACCESS_KEY_ID"] ||= Litestream.configuration.replica_key_id
|
97
|
+
ENV["LITESTREAM_SECRET_ACCESS_KEY"] ||= Litestream.configuration.replica_access_key
|
98
|
+
end
|
99
|
+
|
100
|
+
dir, file = File.split(database)
|
101
|
+
ext = File.extname(file)
|
102
|
+
base = File.basename(file, ext)
|
103
|
+
now = Time.now.utc.strftime("%Y%m%d%H%M%S")
|
104
|
+
|
105
|
+
args = {
|
106
|
+
"--config" => Rails.root.join("config", "litestream.yml").to_s,
|
107
|
+
"-o" => File.join(dir, "#{base}-#{now}#{ext}")
|
108
|
+
}.merge(argv).to_a.flatten.compact
|
109
|
+
|
110
|
+
command = [executable, "restore", *args, database]
|
111
|
+
puts command.inspect
|
112
|
+
|
113
|
+
# To release the resources of the Ruby process, just fork and exit.
|
114
|
+
# The forked process executes litestream and replaces itself.
|
115
|
+
if fork.nil?
|
116
|
+
exec(*command)
|
117
|
+
end
|
118
|
+
end
|
96
119
|
end
|
97
120
|
end
|
@@ -8,7 +8,7 @@ module Litestream
|
|
8
8
|
source_root File.expand_path("templates", __dir__)
|
9
9
|
|
10
10
|
def copy_config_file
|
11
|
-
template "config.yml", "config/litestream.yml"
|
11
|
+
template "config.yml.erb", "config/litestream.yml"
|
12
12
|
end
|
13
13
|
|
14
14
|
def copy_initializer_file
|
@@ -27,6 +27,16 @@ module Litestream
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def production_sqlite_databases
|
34
|
+
ActiveRecord::Base
|
35
|
+
.configurations
|
36
|
+
.configs_for(env_name: "production", include_hidden: true)
|
37
|
+
.select { |config| ["sqlite3", "litedb"].include? config.adapter }
|
38
|
+
.map(&:database)
|
39
|
+
end
|
30
40
|
end
|
31
41
|
end
|
32
42
|
end
|
@@ -10,8 +10,12 @@
|
|
10
10
|
#
|
11
11
|
# For more details, see: https://litestream.io/reference/config/
|
12
12
|
dbs:
|
13
|
-
|
13
|
+
<%- production_sqlite_databases.each do |database| -%>
|
14
|
+
- path: <%= database %>
|
14
15
|
replicas:
|
15
|
-
-
|
16
|
+
- type: s3
|
17
|
+
bucket: $LITESTREAM_REPLICA_BUCKET
|
18
|
+
path: <%= database %>
|
16
19
|
access-key-id: $LITESTREAM_ACCESS_KEY_ID
|
17
20
|
secret-access-key: $LITESTREAM_SECRET_ACCESS_KEY
|
21
|
+
<%- end -%>
|
@@ -1,30 +1,25 @@
|
|
1
1
|
# Use this hook to configure the litestream-ruby gem.
|
2
2
|
# All configuration options will be available as environment variables, e.g.
|
3
|
-
# config.
|
3
|
+
# config.replica_bucket becomes LITESTREAM_REPLICA_BUCKET
|
4
4
|
# This allows you to configure Litestream using Rails encrypted credentials,
|
5
5
|
# or some other mechanism where the values are only avaialble at runtime.
|
6
6
|
|
7
7
|
Litestream.configure do |config|
|
8
8
|
# An example of using Rails encrypted credentials to configure Litestream.
|
9
9
|
# litestream_credentials = Rails.application.credentials.litestream
|
10
|
-
#
|
11
|
-
# The absolute or relative path to a SQLite database file.
|
12
|
-
# Litestream will monitor this file for changes and replicate them to the
|
13
|
-
# any of the configured replicas specified for this database in the
|
14
|
-
# `litestream.yml` configuration file.
|
15
|
-
# When using SQLite as your database engine for ActiveRecord, you should always
|
16
|
-
# set this to the path of your SQLite database file. You can do so using Rails'
|
17
|
-
# existing knowledge of the database path.
|
18
|
-
# config.database_path = ActiveRecord::Base.connection_db_config.database
|
19
10
|
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
11
|
+
# Replica-specific bucket location.
|
12
|
+
# This will be your bucket's URL without the `https://` prefix.
|
13
|
+
# For example, if you used DigitalOcean Spaces, your bucket URL could look like:
|
14
|
+
# https://myapp.fra1.digitaloceanspaces.com
|
15
|
+
# And so you should set your `replica_bucket` to:
|
16
|
+
# myapp.fra1.digitaloceanspaces.com
|
17
|
+
# Litestream supports Azure Blog Storage, Backblaze B2, DigitalOcean Spaces,
|
23
18
|
# Scaleway Object Storage, Google Cloud Storage, Linode Object Storage, and
|
24
19
|
# any SFTP server.
|
25
20
|
# In this example, we are using Rails encrypted credentials to store the URL to
|
26
21
|
# our storage provider bucket.
|
27
|
-
# config.
|
22
|
+
# config.replica_bucket = litestream_credentials.replica_bucket
|
28
23
|
|
29
24
|
# Replica-specific authentication key.
|
30
25
|
# Litestream needs authentication credentials to access your storage provider bucket.
|
data/lib/litestream/version.rb
CHANGED
data/lib/litestream.rb
CHANGED
@@ -11,10 +11,9 @@ module Litestream
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class Configuration
|
14
|
-
attr_accessor :database_path, :
|
14
|
+
attr_accessor :database_path, :replica_bucket, :replica_key_id, :replica_access_key
|
15
15
|
|
16
16
|
def initialize
|
17
|
-
@mailer_sender = "donotreply@example.com"
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
@@ -6,15 +6,14 @@ namespace :litestream do
|
|
6
6
|
next
|
7
7
|
end
|
8
8
|
|
9
|
-
puts "
|
10
|
-
puts "LITESTREAM_REPLICA_URL=#{Litestream.configuration.replica_url}"
|
9
|
+
puts "LITESTREAM_REPLICA_BUCKET=#{Litestream.configuration.replica_bucket}"
|
11
10
|
puts "LITESTREAM_ACCESS_KEY_ID=#{Litestream.configuration.replica_key_id}"
|
12
11
|
puts "LITESTREAM_SECRET_ACCESS_KEY=#{Litestream.configuration.replica_access_key}"
|
13
12
|
|
14
13
|
true
|
15
14
|
end
|
16
15
|
|
17
|
-
desc
|
16
|
+
desc 'Monitor and continuously replicate SQLite databases defined in your config file, e.g. rake litestream:replicate -- -exec "foreman start"'
|
18
17
|
task replicate: :environment do
|
19
18
|
options = {}
|
20
19
|
if (separator_index = ARGV.index("--"))
|
@@ -25,4 +24,16 @@ namespace :litestream do
|
|
25
24
|
|
26
25
|
Litestream::Commands.replicate(options)
|
27
26
|
end
|
27
|
+
|
28
|
+
desc "Restore a SQLite database from a Litestream replica, e.g. rake litestream:restore -- -database=storage/production.sqlite3"
|
29
|
+
task restore: :environment do
|
30
|
+
options = {}
|
31
|
+
if (separator_index = ARGV.index("--"))
|
32
|
+
ARGV.slice(separator_index + 1, ARGV.length)
|
33
|
+
.map { |pair| pair.split("=") }
|
34
|
+
.each { |opt| options[opt[0]] = opt[1] || nil }
|
35
|
+
end
|
36
|
+
|
37
|
+
Litestream::Commands.restore(options.delete("--database") || options.delete("-database"), options)
|
38
|
+
end
|
28
39
|
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.4.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-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -69,7 +69,7 @@ files:
|
|
69
69
|
- lib/litestream.rb
|
70
70
|
- lib/litestream/commands.rb
|
71
71
|
- lib/litestream/generators/litestream/install_generator.rb
|
72
|
-
- lib/litestream/generators/litestream/templates/config.yml
|
72
|
+
- lib/litestream/generators/litestream/templates/config.yml.erb
|
73
73
|
- lib/litestream/generators/litestream/templates/initializer.rb
|
74
74
|
- lib/litestream/railtie.rb
|
75
75
|
- lib/litestream/upstream.rb
|