synco 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +4 -0
- data/.simplecov +9 -0
- data/.travis.yml +14 -0
- data/Gemfile +11 -0
- data/README.md +246 -0
- data/Rakefile +8 -0
- data/bin/synco +30 -0
- data/lib/synco.rb +51 -0
- data/lib/synco/command.rb +71 -0
- data/lib/synco/command/disk.rb +55 -0
- data/lib/synco/command/prune.rb +166 -0
- data/lib/synco/command/rotate.rb +86 -0
- data/lib/synco/command/spawn.rb +39 -0
- data/lib/synco/compact_formatter.rb +115 -0
- data/lib/synco/controller.rb +119 -0
- data/lib/synco/directory.rb +60 -0
- data/lib/synco/disk.rb +68 -0
- data/lib/synco/method.rb +56 -0
- data/lib/synco/methods/rsync.rb +162 -0
- data/lib/synco/methods/scp.rb +44 -0
- data/lib/synco/methods/zfs.rb +60 -0
- data/lib/synco/scope.rb +247 -0
- data/lib/synco/script.rb +128 -0
- data/lib/synco/server.rb +90 -0
- data/lib/synco/shell.rb +44 -0
- data/lib/synco/shells/ssh.rb +52 -0
- data/lib/synco/version.rb +23 -0
- data/media/LSync Logo.artx/Preview/preview.png +0 -0
- data/media/LSync Logo.artx/QuickLook/Preview.pdf +0 -0
- data/media/LSync Logo.artx/doc.thread +0 -0
- data/media/LSync Logo.png +0 -0
- data/spec/synco/backup_script.rb +63 -0
- data/spec/synco/directory_spec.rb +33 -0
- data/spec/synco/local_backup.rb +56 -0
- data/spec/synco/local_sync.rb +91 -0
- data/spec/synco/method_spec.rb +62 -0
- data/spec/synco/rsync_spec.rb +89 -0
- data/spec/synco/scp_spec.rb +58 -0
- data/spec/synco/script_spec.rb +51 -0
- data/spec/synco/shell_spec.rb +42 -0
- data/spec/synco/usb_spec.rb +76 -0
- data/spec/synco/zfs_spec.rb +50 -0
- data/synco.gemspec +35 -0
- metadata +254 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fedf0385eb4c7050534dd617e760cd8f103407bd
|
4
|
+
data.tar.gz: 510351b706b78342f9c098300fb7fa6ccff59b77
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 84434a2dc282d598b3e886c534a20e142c1c015915f3e516a85a065c9e08f5e0abd7e7cd7fa79892bea5f272f0bce8653d2661f3274d8c2f4d1b09477030f614
|
7
|
+
data.tar.gz: fba66451cbd62dd7885add0fc05f9dd45d632bb98512777f56e4bfb92f7fd48622b29898a6f0a6660db251775d5e65afcfda3bbd804a345abd2932ce64cf7c82
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/.simplecov
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
# Synco
|
2
|
+
|
3
|
+
Synco is a tool for scripted synchronization and backups. It provides a custom Ruby DSL for describing backup and synchronization tasks involving one more more system and disk. It is designed to provide flexibility while reducing the complexity multi-server backups.
|
4
|
+
|
5
|
+
* Single and multi-server data synchronization.
|
6
|
+
* Incremental backups both locally and remotely.
|
7
|
+
* Backup staging and coordination.
|
8
|
+
* Backup verification using [Fingerprint](https://github.com/ioquatix/fingerprint).
|
9
|
+
* Data backup redundancy controlled via DNS.
|
10
|
+
|
11
|
+
[![Build Status](https://secure.travis-ci.org/ioquatix/synco.svg)](http://travis-ci.org/ioquatix/synco)
|
12
|
+
[![Code Climate](https://codeclimate.com/github/ioquatix/synco.svg)](https://codeclimate.com/github/ioquatix/synco)
|
13
|
+
[![Coverage Status](https://coveralls.io/repos/ioquatix/synco/badge.svg)](https://coveralls.io/r/ioquatix/synco)
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'synco'
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install synco
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
Synco imposes a particular structure regarding the organisation of backup scripts: Backup scripts involve a set of servers and directories. A server is a logical unit where files are available or stored. Directories are relative paths which are resolved relative to a server's root path.
|
32
|
+
|
33
|
+
A simple backup script might look something like this:
|
34
|
+
|
35
|
+
#!/usr/bin/env ruby
|
36
|
+
|
37
|
+
require 'synco'
|
38
|
+
require 'synco/methods/rsync'
|
39
|
+
|
40
|
+
Synco::run_script do |script|
|
41
|
+
script.method = Synco::Methods::RSync.new(archive: true)
|
42
|
+
|
43
|
+
server(:master) do |server|
|
44
|
+
server.host = "server.example.com"
|
45
|
+
server.root = "/"
|
46
|
+
end
|
47
|
+
|
48
|
+
server(:backup) do |server|
|
49
|
+
server.host = "backup.example.com"
|
50
|
+
server.root = "/tank/backups/server.example.com"
|
51
|
+
end
|
52
|
+
|
53
|
+
backup('etc', 'var', 'srv', 'home',
|
54
|
+
arguments: %W{--exclude cache/ --exclude tmp/}
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
This will produce an identical copy using rsync of the specified directories. As an example `server.example.com:/etc` would be copied to `backup.example.com:/tank/backups/server.example.com/etc`.
|
59
|
+
|
60
|
+
### RSync Snapshots
|
61
|
+
|
62
|
+
Building on the above backup, you can use `Synco::Methods::RSyncSnapshot` which supports snapshot based backups. It creates a snapshot into a sub-directory called `latest.snapshot` and uses RSync's `--link-dest` to hard-link files when unchanged. Synco provides scripts to rotate and prune these backups as required, but you must invoke them as part of the script:
|
63
|
+
|
64
|
+
server(:backup) do |server|
|
65
|
+
server.host = "backup.example.com"
|
66
|
+
server.root = "/"
|
67
|
+
|
68
|
+
server.on(:success) do
|
69
|
+
run "synco", "rotate", chdir: target_server.root
|
70
|
+
run "synco", "prune", chdir: target_server.root
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
These commands can also be run from the command line.
|
75
|
+
|
76
|
+
rotate [--format <name>] [--latest <name>] [--snapshot <name>]
|
77
|
+
Rotate a backup snapshot into a timestamped directory.
|
78
|
+
|
79
|
+
[--format <name>] Set the name of the backup rotations, including strftime expansions. Default: %Y.%m.%d-%H.%M.%S
|
80
|
+
[--latest <name>] The name of the latest backup symlink. Default: latest
|
81
|
+
[--snapshot <name>] The name of the in-progress backup snapshot. Default: latest.snapshot
|
82
|
+
|
83
|
+
prune [--hourly <count>] [--daily <count>] [--weekly <count>] [--monthly <count>] [--quarterly <count>] [--yearly <count>] [--format <name>] [--latest <name>] [--keep <new|old>] [--dry]
|
84
|
+
Prune old backups to reduce disk usage according to a given policy.
|
85
|
+
|
86
|
+
[--hourly <count>] Set the number of hourly backups to keep. Default: 24
|
87
|
+
[--daily <count>] Set the number of daily backups to keep. Default: 28
|
88
|
+
[--weekly <count>] Set the number of weekly backups to keep. Default: 52
|
89
|
+
[--monthly <count>] Set the number of monthly backups to keep. Default: 36
|
90
|
+
[--quarterly <count>] Set the number of quaterly backups to keep. Default: 40
|
91
|
+
[--yearly <count>] Set the number of yearly backups to keep. Default: 20
|
92
|
+
[--format <name>] Set the name of the backup rotations, including strftime expansions. Default: %Y.%m.%d-%H.%M.%S
|
93
|
+
[--latest <name>] The name of the latest backup symlink. Default: latest
|
94
|
+
[--keep <new|old>] Keep the younger or older backups within the same period division Default: old
|
95
|
+
[--dry] Print out what would be done rather than doing it.
|
96
|
+
|
97
|
+
### Mounting Disks
|
98
|
+
|
99
|
+
Synco supports mounting disks before the backup begins and unmounting them after done. The specifics of this process may require some adjustment based on your OS. For example on linux, `sudo` is used to invoke `mount` and `umount`.
|
100
|
+
|
101
|
+
server(:destination) do |server|
|
102
|
+
self.mountpoint = '/mnt/backups'
|
103
|
+
self.root = File.join(server.mountpoint, 'laptop')
|
104
|
+
|
105
|
+
server.on(:prepare) do
|
106
|
+
# synco mount uses labels, e.g. the disk partition has LABEL=backups
|
107
|
+
target_server.run "synco", "mount", target_server.mountpoint, 'backups'
|
108
|
+
end
|
109
|
+
|
110
|
+
server.on(:finish) do
|
111
|
+
target_server.run "synco", "unmount", target_server.mountpoint
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
On Linux, you might want to create the file `/etc/sudoers.d/synco` with the following contents:
|
116
|
+
|
117
|
+
%wheel ALL=(root) NOPASSWD: /bin/mount
|
118
|
+
%wheel ALL=(root) NOPASSWD: /bin/umount
|
119
|
+
|
120
|
+
Please make sure you take the time to educate yourself on the security of such a setup.
|
121
|
+
|
122
|
+
### Database Backups
|
123
|
+
|
124
|
+
If you'd like to dump data before running the backup, it's possible using the event handling mechanisms:
|
125
|
+
|
126
|
+
server(:master) do |server|
|
127
|
+
server.host = "server.example.com"
|
128
|
+
server.root = "/"
|
129
|
+
|
130
|
+
server.on(:prepare) do
|
131
|
+
# Dump MySQL to /srv/mysql
|
132
|
+
run '/etc/lsync/mysql-backup.sh'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
The exact contents of `mysql-backup.sh` will depend on your requirements, but here is an example:
|
137
|
+
|
138
|
+
#!/usr/bin/env bash
|
139
|
+
|
140
|
+
BACKUP_DIR=/srv/mysql
|
141
|
+
MYSQL=/usr/bin/mysql
|
142
|
+
MYSQLDUMP=/usr/bin/mysqldump
|
143
|
+
|
144
|
+
databases=`mysql --user=backup -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|_test|_restore)"`
|
145
|
+
|
146
|
+
# http://stackoverflow.com/questions/451404/how-to-obtain-a-correct-dump-using-mysqldump-and-single-transaction-when-ddl-is
|
147
|
+
MYSQLDUMP_OPTIONS="--force --skip-opt --single-transaction --add-drop-table --create-options --quick --extended-insert --set-charset --disable-keys"
|
148
|
+
|
149
|
+
for db in $databases; do
|
150
|
+
echo "Dumping database $db to $BACKUP_DIR/$db.sql.xz..."
|
151
|
+
mysqldump --user=backup $MYSQLDUMP_OPTIONS --databases $db | xz > "$BACKUP_DIR/$db.sql.xz"
|
152
|
+
done
|
153
|
+
|
154
|
+
### Fingerprint Integration
|
155
|
+
|
156
|
+
It is possible to make a [cryptographic checksum of the data](https://github.com/ioquatix/fingerprint). On a filesystem that support immutable snapshots, you can do this before the data is copied. For traditional filesystems, you generally need to do this afterwards.
|
157
|
+
|
158
|
+
server(:master) do |server|
|
159
|
+
server.host = "server.example.com"
|
160
|
+
server.root = "/"
|
161
|
+
|
162
|
+
server.on(:success) do
|
163
|
+
# Run fingerprint on the backup data:
|
164
|
+
run 'fingerprint', '--root', target_server.root, 'analyze'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
Fingerprint is used in many of the specs to verify file copies.
|
169
|
+
|
170
|
+
### ZFS Snapshots
|
171
|
+
|
172
|
+
*This part of Synco is still under heavy development*
|
173
|
+
|
174
|
+
Synco can manage synchronization and backups of ZFS partitions. However, to use the standard tools, it is necessary to enable `zfs_admin_snapshot`, in `/etc/modprobe.d/zfs.conf`:
|
175
|
+
|
176
|
+
options zfs zfs_admin_snapshot=1
|
177
|
+
|
178
|
+
Propagate user permissions for the ZFS partition:
|
179
|
+
|
180
|
+
sudo zfs allow -ld -u `whoami` create,mount,send,receive,snapshot tank/test
|
181
|
+
|
182
|
+
### Backup staging
|
183
|
+
|
184
|
+
Synco in a previous life supported backup staging. However, at this time it's not available except in a very limited form: backup scripts which use `Synco.run_script` use explicit locking so that it's not possible to run the same backup at the same time. In the future, staging sequential and parallel backups will be added.
|
185
|
+
|
186
|
+
### DNS Failover
|
187
|
+
|
188
|
+
**This behaviour is not well tested**
|
189
|
+
|
190
|
+
Synco uses DNS to resolve the master server. This allows for bi-directional synchronization and other interesting setups.
|
191
|
+
|
192
|
+
Firstly, a backup script defaults to the server with the name `:master` as the master, where data is replicated FROM.
|
193
|
+
|
194
|
+
However, it is possible instead to specify a hostname, e.g. `primary.example.com`. Then, specify several servers, e.g. `s01.example.com`, `s02.example.com` and so on:
|
195
|
+
|
196
|
+
Synco::run_script do |script|
|
197
|
+
script.method = Synco::Methods::RSync.new(archive: true)
|
198
|
+
|
199
|
+
script.master = "primary.example.com"
|
200
|
+
|
201
|
+
server("s01.example.com") do |server|
|
202
|
+
server.root = "/"
|
203
|
+
end
|
204
|
+
|
205
|
+
server("s02.example.com") do |server|
|
206
|
+
server.root = "/"
|
207
|
+
end
|
208
|
+
|
209
|
+
backup('srv/http',
|
210
|
+
arguments: %W{--exclude cache/ --exclude tmp/}
|
211
|
+
)
|
212
|
+
end
|
213
|
+
|
214
|
+
When you run the script, the behaviour will depend on whether `primary.example.com` points to `s01.example.com` or `s02.example.com`. The data will always be copied from the master server to the other servers.
|
215
|
+
|
216
|
+
## Contributing
|
217
|
+
|
218
|
+
1. Fork it
|
219
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
220
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
221
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
222
|
+
5. Create new Pull Request
|
223
|
+
|
224
|
+
## License
|
225
|
+
|
226
|
+
Released under the MIT license.
|
227
|
+
|
228
|
+
Copyright, 2016, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
|
229
|
+
|
230
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
231
|
+
of this software and associated documentation files (the "Software"), to deal
|
232
|
+
in the Software without restriction, including without limitation the rights
|
233
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
234
|
+
copies of the Software, and to permit persons to whom the Software is
|
235
|
+
furnished to do so, subject to the following conditions:
|
236
|
+
|
237
|
+
The above copyright notice and this permission notice shall be included in
|
238
|
+
all copies or substantial portions of the Software.
|
239
|
+
|
240
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
241
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
242
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
243
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
244
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
245
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
246
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
data/bin/synco
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
# This script takes a given path, and renames it with the given format.
|
24
|
+
# It then ensures that there is a symlink called "latest" that points
|
25
|
+
# to the renamed directory.
|
26
|
+
|
27
|
+
require 'synco/command'
|
28
|
+
|
29
|
+
application = Synco::Command::Top.new(ARGV)
|
30
|
+
application.invoke
|
data/lib/synco.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'yaml'
|
22
|
+
require 'socket'
|
23
|
+
require 'set'
|
24
|
+
require 'logger'
|
25
|
+
|
26
|
+
require_relative 'synco/version'
|
27
|
+
require_relative 'synco/script'
|
28
|
+
require_relative 'synco/scope'
|
29
|
+
|
30
|
+
require 'fileutils'
|
31
|
+
require 'optparse'
|
32
|
+
|
33
|
+
require 'lockfile'
|
34
|
+
|
35
|
+
module Synco
|
36
|
+
# Run a prepared backup script using a lockfile.
|
37
|
+
def self.run_script(*arguments, **options, &block)
|
38
|
+
script = Synco::Script.build(*arguments, **options, &block)
|
39
|
+
lockfile_path = $0 + ".lock"
|
40
|
+
|
41
|
+
# script.on(:failure) do |exception|
|
42
|
+
# logger.error{exception}
|
43
|
+
#
|
44
|
+
# raise
|
45
|
+
# end
|
46
|
+
|
47
|
+
Lockfile.new(lockfile_path, :retries => 0) do
|
48
|
+
Runner.new(script).call
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
# This script takes a given path, and renames it with the given format.
|
22
|
+
# It then ensures that there is a symlink called "latest" that points
|
23
|
+
# to the renamed directory.
|
24
|
+
|
25
|
+
require 'samovar'
|
26
|
+
|
27
|
+
require_relative 'command/spawn'
|
28
|
+
require_relative 'command/rotate'
|
29
|
+
require_relative 'command/prune'
|
30
|
+
require_relative 'command/disk'
|
31
|
+
|
32
|
+
module Synco
|
33
|
+
module Command
|
34
|
+
class Top < Samovar::Command
|
35
|
+
self.description = "A backup and synchronizatio tool."
|
36
|
+
|
37
|
+
options do
|
38
|
+
option '--root <path>', "Work in the given root directory."
|
39
|
+
option '-h/--help', "Print out help information."
|
40
|
+
option '-v/--version', "Print out the application version."
|
41
|
+
end
|
42
|
+
|
43
|
+
def chdir(&block)
|
44
|
+
if root = @options[:root]
|
45
|
+
Dir.chdir(root, &block)
|
46
|
+
else
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
nested '<command>',
|
52
|
+
'spawn' => Spawn,
|
53
|
+
'rotate' => Rotate,
|
54
|
+
'prune' => Prune,
|
55
|
+
'mount' => Mount,
|
56
|
+
'unmount' => Unmount
|
57
|
+
|
58
|
+
def invoke(program_name: File.basename($0))
|
59
|
+
if @options[:version]
|
60
|
+
puts "synco v#{Synco::VERSION}"
|
61
|
+
elsif @options[:help] or @command.nil?
|
62
|
+
print_usage(program_name)
|
63
|
+
else
|
64
|
+
chdir do
|
65
|
+
@command.invoke(self)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|