backup-remote 0.0.2
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 +7 -0
- data/README.md +112 -0
- data/bin/backup-remote +5 -0
- data/lib/backup.rb +155 -0
- data/lib/backup/archive.rb +170 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/cleaner.rb +116 -0
- data/lib/backup/cli.rb +374 -0
- data/lib/backup/cloud_io/base.rb +41 -0
- data/lib/backup/cloud_io/cloud_files.rb +298 -0
- data/lib/backup/cloud_io/s3.rb +260 -0
- data/lib/backup/compressor/base.rb +35 -0
- data/lib/backup/compressor/bzip2.rb +39 -0
- data/lib/backup/compressor/custom.rb +53 -0
- data/lib/backup/compressor/gzip.rb +74 -0
- data/lib/backup/config.rb +121 -0
- data/lib/backup/config/dsl.rb +106 -0
- data/lib/backup/config/helpers.rb +143 -0
- data/lib/backup/database/base.rb +85 -0
- data/lib/backup/database/mongodb.rb +187 -0
- data/lib/backup/database/mysql.rb +192 -0
- data/lib/backup/database/openldap.rb +95 -0
- data/lib/backup/database/postgresql.rb +133 -0
- data/lib/backup/database/redis.rb +179 -0
- data/lib/backup/database/remote_mysql.rb +248 -0
- data/lib/backup/database/riak.rb +82 -0
- data/lib/backup/database/sqlite.rb +57 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +747 -0
- data/lib/backup/encryptor/open_ssl.rb +77 -0
- data/lib/backup/errors.rb +58 -0
- data/lib/backup/logger.rb +199 -0
- data/lib/backup/logger/console.rb +51 -0
- data/lib/backup/logger/fog_adapter.rb +29 -0
- data/lib/backup/logger/logfile.rb +133 -0
- data/lib/backup/logger/syslog.rb +116 -0
- data/lib/backup/model.rb +479 -0
- data/lib/backup/notifier/base.rb +128 -0
- data/lib/backup/notifier/campfire.rb +63 -0
- data/lib/backup/notifier/command.rb +102 -0
- data/lib/backup/notifier/datadog.rb +107 -0
- data/lib/backup/notifier/flowdock.rb +103 -0
- data/lib/backup/notifier/hipchat.rb +118 -0
- data/lib/backup/notifier/http_post.rb +117 -0
- data/lib/backup/notifier/mail.rb +249 -0
- data/lib/backup/notifier/nagios.rb +69 -0
- data/lib/backup/notifier/pagerduty.rb +81 -0
- data/lib/backup/notifier/prowl.rb +68 -0
- data/lib/backup/notifier/pushover.rb +74 -0
- data/lib/backup/notifier/ses.rb +105 -0
- data/lib/backup/notifier/slack.rb +148 -0
- data/lib/backup/notifier/twitter.rb +58 -0
- data/lib/backup/notifier/zabbix.rb +63 -0
- data/lib/backup/package.rb +55 -0
- data/lib/backup/packager.rb +107 -0
- data/lib/backup/pipeline.rb +128 -0
- data/lib/backup/remote/command.rb +82 -0
- data/lib/backup/splitter.rb +76 -0
- data/lib/backup/storage/base.rb +69 -0
- data/lib/backup/storage/cloud_files.rb +158 -0
- data/lib/backup/storage/cycler.rb +75 -0
- data/lib/backup/storage/dropbox.rb +212 -0
- data/lib/backup/storage/ftp.rb +112 -0
- data/lib/backup/storage/local.rb +64 -0
- data/lib/backup/storage/qiniu.rb +65 -0
- data/lib/backup/storage/rsync.rb +248 -0
- data/lib/backup/storage/s3.rb +156 -0
- data/lib/backup/storage/scp.rb +67 -0
- data/lib/backup/storage/sftp.rb +82 -0
- data/lib/backup/syncer/base.rb +70 -0
- data/lib/backup/syncer/cloud/base.rb +179 -0
- data/lib/backup/syncer/cloud/cloud_files.rb +83 -0
- data/lib/backup/syncer/cloud/local_file.rb +100 -0
- data/lib/backup/syncer/cloud/s3.rb +110 -0
- data/lib/backup/syncer/rsync/base.rb +54 -0
- data/lib/backup/syncer/rsync/local.rb +31 -0
- data/lib/backup/syncer/rsync/pull.rb +51 -0
- data/lib/backup/syncer/rsync/push.rb +205 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/utilities.rb +224 -0
- data/lib/backup/version.rb +5 -0
- data/templates/cli/archive +28 -0
- data/templates/cli/compressor/bzip2 +4 -0
- data/templates/cli/compressor/custom +7 -0
- data/templates/cli/compressor/gzip +4 -0
- data/templates/cli/config +123 -0
- data/templates/cli/databases/mongodb +15 -0
- data/templates/cli/databases/mysql +18 -0
- data/templates/cli/databases/openldap +24 -0
- data/templates/cli/databases/postgresql +16 -0
- data/templates/cli/databases/redis +16 -0
- data/templates/cli/databases/riak +17 -0
- data/templates/cli/databases/sqlite +11 -0
- data/templates/cli/encryptor/gpg +27 -0
- data/templates/cli/encryptor/openssl +9 -0
- data/templates/cli/model +26 -0
- data/templates/cli/notifier/zabbix +15 -0
- data/templates/cli/notifiers/campfire +12 -0
- data/templates/cli/notifiers/command +32 -0
- data/templates/cli/notifiers/datadog +57 -0
- data/templates/cli/notifiers/flowdock +16 -0
- data/templates/cli/notifiers/hipchat +16 -0
- data/templates/cli/notifiers/http_post +32 -0
- data/templates/cli/notifiers/mail +24 -0
- data/templates/cli/notifiers/nagios +13 -0
- data/templates/cli/notifiers/pagerduty +12 -0
- data/templates/cli/notifiers/prowl +11 -0
- data/templates/cli/notifiers/pushover +11 -0
- data/templates/cli/notifiers/ses +15 -0
- data/templates/cli/notifiers/slack +22 -0
- data/templates/cli/notifiers/twitter +13 -0
- data/templates/cli/splitter +7 -0
- data/templates/cli/storages/cloud_files +11 -0
- data/templates/cli/storages/dropbox +20 -0
- data/templates/cli/storages/ftp +13 -0
- data/templates/cli/storages/local +8 -0
- data/templates/cli/storages/qiniu +12 -0
- data/templates/cli/storages/rsync +17 -0
- data/templates/cli/storages/s3 +16 -0
- data/templates/cli/storages/scp +15 -0
- data/templates/cli/storages/sftp +15 -0
- data/templates/cli/syncers/cloud_files +22 -0
- data/templates/cli/syncers/rsync_local +20 -0
- data/templates/cli/syncers/rsync_pull +28 -0
- data/templates/cli/syncers/rsync_push +28 -0
- data/templates/cli/syncers/s3 +27 -0
- data/templates/general/links +3 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +16 -0
- data/templates/notifier/mail/success.erb +16 -0
- data/templates/notifier/mail/warning.erb +16 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +1122 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6348ea6aeaeb00662de0ab77653a06d502bda873
|
|
4
|
+
data.tar.gz: a3b3dc874abda57381f51cce9304a4c3ce7cec02
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 59d8e1ff63b2282972f5d9f84b128e4a84c6599437977aa49f94540a627bffbae85887e821d49313fca9c50250472ca7293d4e89e6aee2d9550e1ad8a85e31b9
|
|
7
|
+
data.tar.gz: 0ef397f317bcb405cd93716e7a207d30137c085a475e1f11bad4606730cc402c95e8437c4a8d2fe1ff4771aa42b49b9e888e5cbe410ed62ee9a49930a84e1785
|
data/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Backup Remote
|
|
2
|
+
===========
|
|
3
|
+
Backup-remote gem extends [Backup gem](https://github.com/backup/backup) to perform backups on remote servers.
|
|
4
|
+
|
|
5
|
+
If you use backup gem you should run `backup perform` on the machine where resources (files, databases) are located.
|
|
6
|
+
|
|
7
|
+
This gem adds support for models to perform backups on a remote server.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Backup is a system utility for Linux and Mac OS X, distributed as a RubyGem, that allows you to easily perform backup
|
|
12
|
+
operations. It provides an elegant DSL in Ruby for _modeling_ your backups.
|
|
13
|
+
Backup has built-in support for various databases, storage protocols/services, syncers, compressors, encryptors and notifiers which you can mix and match.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# How it works
|
|
18
|
+
|
|
19
|
+
Backup process:
|
|
20
|
+
|
|
21
|
+
* specify server connection options in your model
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Model.new(:my_backup, 'My Backup') do
|
|
25
|
+
database RemoteMySQL do |db|
|
|
26
|
+
# options for server
|
|
27
|
+
db.server_host = "server1.com"
|
|
28
|
+
db.server_ssh_user = "username"
|
|
29
|
+
db.server_ssh_password = "mypwd"
|
|
30
|
+
db.server_ssh_key = "/path/to/ssh/key"
|
|
31
|
+
|
|
32
|
+
# other options for resource
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
...
|
|
37
|
+
end
|
|
38
|
+
````
|
|
39
|
+
|
|
40
|
+
* perform backup - run script `backup peform` from the backup server
|
|
41
|
+
```
|
|
42
|
+
backup-remote perform -t my_backup
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
* it will connect to the remote server by SSH and run command remotely which creates a backup file
|
|
46
|
+
* then it downloads the archive file from the remote server to the backup server
|
|
47
|
+
* finally, it performs all operations with backup file, like storing file to storages, etc. as gem backup does.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
It uses SSHKit to connect to server by SSH.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Options
|
|
57
|
+
|
|
58
|
+
Options for SSH connection:
|
|
59
|
+
* server_host - host name or IP
|
|
60
|
+
* server_ssh_user - user name to connect by SSH
|
|
61
|
+
* server_ssh_password - not used if server_ssh-key is provided
|
|
62
|
+
* server_ssh_key - (optional) - path to ssh key
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# Archives
|
|
67
|
+
|
|
68
|
+
## Archive files on a remote server
|
|
69
|
+
|
|
70
|
+
* Use RemoteArchive
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Databases
|
|
77
|
+
|
|
78
|
+
## Backup database on a remote server
|
|
79
|
+
|
|
80
|
+
* Now it is implemented the following databases:
|
|
81
|
+
* RemoteMySQL
|
|
82
|
+
|
|
83
|
+
### RemoteMySQL
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Model.new(:my_backup, 'My Backup') do
|
|
87
|
+
database RemoteMySQL do |db|
|
|
88
|
+
# options for server
|
|
89
|
+
db.server_host = "server1.com"
|
|
90
|
+
db.server_ssh_user = "username"
|
|
91
|
+
db.server_ssh_password = "mypwd"
|
|
92
|
+
db.server_ssh_key = "/path/to/ssh/key"
|
|
93
|
+
|
|
94
|
+
### options for MySQL
|
|
95
|
+
# see http://backup.github.io/backup/v4/database-mysql/
|
|
96
|
+
|
|
97
|
+
...
|
|
98
|
+
end
|
|
99
|
+
..
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
````
|
|
103
|
+
|
|
104
|
+
# Custom backup command
|
|
105
|
+
|
|
106
|
+
* Run custom command to create a backup archive on a remote server
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# Backup gem
|
|
110
|
+
[Installation]: http://backup.github.io/backup/v4/installation
|
|
111
|
+
[Release Notes]: http://backup.github.io/backup/v4/release-notes
|
|
112
|
+
[Documentation]: http://backup.github.io/backup/v4
|
data/bin/backup-remote
ADDED
data/lib/backup.rb
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
# Load Ruby Core Libraries
|
|
4
|
+
require 'time'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'tempfile'
|
|
7
|
+
require 'syslog'
|
|
8
|
+
require 'yaml'
|
|
9
|
+
require 'etc'
|
|
10
|
+
require 'forwardable'
|
|
11
|
+
require 'thread'
|
|
12
|
+
|
|
13
|
+
require 'open4'
|
|
14
|
+
require 'thor'
|
|
15
|
+
require 'shellwords'
|
|
16
|
+
|
|
17
|
+
require 'excon'
|
|
18
|
+
# Include response.inspect in error messages.
|
|
19
|
+
Excon.defaults[:debug_response] = true
|
|
20
|
+
# Excon should not retry failed requests. We handle that.
|
|
21
|
+
Excon.defaults[:middlewares].delete(Excon::Middleware::Idempotent)
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# The Backup Ruby Gem
|
|
25
|
+
module Backup
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Backup's internal paths
|
|
29
|
+
LIBRARY_PATH = File.join(File.dirname(__FILE__), 'backup')
|
|
30
|
+
STORAGE_PATH = File.join(LIBRARY_PATH, 'storage')
|
|
31
|
+
SYNCER_PATH = File.join(LIBRARY_PATH, 'syncer')
|
|
32
|
+
DATABASE_PATH = File.join(LIBRARY_PATH, 'database')
|
|
33
|
+
COMPRESSOR_PATH = File.join(LIBRARY_PATH, 'compressor')
|
|
34
|
+
ENCRYPTOR_PATH = File.join(LIBRARY_PATH, 'encryptor')
|
|
35
|
+
NOTIFIER_PATH = File.join(LIBRARY_PATH, 'notifier')
|
|
36
|
+
TEMPLATE_PATH = File.expand_path('../../templates', __FILE__)
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Autoload Backup storage files
|
|
40
|
+
module Storage
|
|
41
|
+
autoload :Base, File.join(STORAGE_PATH, 'base')
|
|
42
|
+
autoload :Cycler, File.join(STORAGE_PATH, 'cycler')
|
|
43
|
+
autoload :S3, File.join(STORAGE_PATH, 's3')
|
|
44
|
+
autoload :CloudFiles, File.join(STORAGE_PATH, 'cloud_files')
|
|
45
|
+
autoload :Ninefold, File.join(STORAGE_PATH, 'ninefold')
|
|
46
|
+
autoload :Dropbox, File.join(STORAGE_PATH, 'dropbox')
|
|
47
|
+
autoload :FTP, File.join(STORAGE_PATH, 'ftp')
|
|
48
|
+
autoload :SFTP, File.join(STORAGE_PATH, 'sftp')
|
|
49
|
+
autoload :SCP, File.join(STORAGE_PATH, 'scp')
|
|
50
|
+
autoload :RSync, File.join(STORAGE_PATH, 'rsync')
|
|
51
|
+
autoload :Local, File.join(STORAGE_PATH, 'local')
|
|
52
|
+
autoload :Qiniu, File.join(STORAGE_PATH, 'qiniu')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Autoload Backup syncer files
|
|
57
|
+
module Syncer
|
|
58
|
+
autoload :Base, File.join(SYNCER_PATH, 'base')
|
|
59
|
+
module Cloud
|
|
60
|
+
autoload :Base, File.join(SYNCER_PATH, 'cloud', 'base')
|
|
61
|
+
autoload :LocalFile, File.join(SYNCER_PATH, 'cloud', 'local_file')
|
|
62
|
+
autoload :CloudFiles, File.join(SYNCER_PATH, 'cloud', 'cloud_files')
|
|
63
|
+
autoload :S3, File.join(SYNCER_PATH, 'cloud', 's3')
|
|
64
|
+
end
|
|
65
|
+
module RSync
|
|
66
|
+
autoload :Base, File.join(SYNCER_PATH, 'rsync', 'base')
|
|
67
|
+
autoload :Local, File.join(SYNCER_PATH, 'rsync', 'local')
|
|
68
|
+
autoload :Push, File.join(SYNCER_PATH, 'rsync', 'push')
|
|
69
|
+
autoload :Pull, File.join(SYNCER_PATH, 'rsync', 'pull')
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# Autoload Backup database files
|
|
75
|
+
module Database
|
|
76
|
+
autoload :Base, File.join(DATABASE_PATH, 'base')
|
|
77
|
+
autoload :MySQL, File.join(DATABASE_PATH, 'mysql')
|
|
78
|
+
autoload :PostgreSQL, File.join(DATABASE_PATH, 'postgresql')
|
|
79
|
+
autoload :MongoDB, File.join(DATABASE_PATH, 'mongodb')
|
|
80
|
+
autoload :Redis, File.join(DATABASE_PATH, 'redis')
|
|
81
|
+
autoload :Riak, File.join(DATABASE_PATH, 'riak')
|
|
82
|
+
autoload :OpenLDAP, File.join(DATABASE_PATH, 'openldap')
|
|
83
|
+
autoload :SQLite, File.join(DATABASE_PATH, 'sqlite')
|
|
84
|
+
|
|
85
|
+
autoload :RemoteMySQL, File.join(DATABASE_PATH, 'remote_mysql')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# Autoload compressor files
|
|
90
|
+
module Compressor
|
|
91
|
+
autoload :Base, File.join(COMPRESSOR_PATH, 'base')
|
|
92
|
+
autoload :Gzip, File.join(COMPRESSOR_PATH, 'gzip')
|
|
93
|
+
autoload :Bzip2, File.join(COMPRESSOR_PATH, 'bzip2')
|
|
94
|
+
autoload :Custom, File.join(COMPRESSOR_PATH, 'custom')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# Autoload encryptor files
|
|
99
|
+
module Encryptor
|
|
100
|
+
autoload :Base, File.join(ENCRYPTOR_PATH, 'base')
|
|
101
|
+
autoload :OpenSSL, File.join(ENCRYPTOR_PATH, 'open_ssl')
|
|
102
|
+
autoload :GPG, File.join(ENCRYPTOR_PATH, 'gpg')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# Autoload notification files
|
|
107
|
+
module Notifier
|
|
108
|
+
autoload :Base, File.join(NOTIFIER_PATH, 'base')
|
|
109
|
+
autoload :Mail, File.join(NOTIFIER_PATH, 'mail')
|
|
110
|
+
autoload :Twitter, File.join(NOTIFIER_PATH, 'twitter')
|
|
111
|
+
autoload :Campfire, File.join(NOTIFIER_PATH, 'campfire')
|
|
112
|
+
autoload :Prowl, File.join(NOTIFIER_PATH, 'prowl')
|
|
113
|
+
autoload :Hipchat, File.join(NOTIFIER_PATH, 'hipchat')
|
|
114
|
+
autoload :PagerDuty, File.join(NOTIFIER_PATH, 'pagerduty')
|
|
115
|
+
autoload :Pushover, File.join(NOTIFIER_PATH, 'pushover')
|
|
116
|
+
autoload :Slack, File.join(NOTIFIER_PATH, 'slack')
|
|
117
|
+
autoload :HttpPost, File.join(NOTIFIER_PATH, 'http_post')
|
|
118
|
+
autoload :Nagios, File.join(NOTIFIER_PATH, 'nagios')
|
|
119
|
+
autoload :FlowDock, File.join(NOTIFIER_PATH, 'flowdock')
|
|
120
|
+
autoload :Zabbix, File.join(NOTIFIER_PATH, 'zabbix')
|
|
121
|
+
autoload :DataDog, File.join(NOTIFIER_PATH, 'datadog')
|
|
122
|
+
autoload :Ses, File.join(NOTIFIER_PATH, 'ses')
|
|
123
|
+
autoload :Command, File.join(NOTIFIER_PATH, 'command')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
##
|
|
127
|
+
# Autoload Remote files
|
|
128
|
+
LIB_REMOTE_PATH = File.join(LIBRARY_PATH, 'remote')
|
|
129
|
+
|
|
130
|
+
module Remote
|
|
131
|
+
autoload :Command, File.join(LIB_REMOTE_PATH, 'command')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Require Backup base files
|
|
137
|
+
%w{
|
|
138
|
+
errors
|
|
139
|
+
logger
|
|
140
|
+
utilities
|
|
141
|
+
archive
|
|
142
|
+
binder
|
|
143
|
+
cleaner
|
|
144
|
+
model
|
|
145
|
+
config
|
|
146
|
+
cli
|
|
147
|
+
package
|
|
148
|
+
packager
|
|
149
|
+
pipeline
|
|
150
|
+
splitter
|
|
151
|
+
template
|
|
152
|
+
version
|
|
153
|
+
}.each {|lib| require File.join(LIBRARY_PATH, lib) }
|
|
154
|
+
|
|
155
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
class Archive
|
|
5
|
+
class Error < Backup::Error; end
|
|
6
|
+
|
|
7
|
+
include Utilities::Helpers
|
|
8
|
+
attr_reader :name, :options
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Adds a new Archive to a Backup Model.
|
|
12
|
+
#
|
|
13
|
+
# Backup::Model.new(:my_backup, 'My Backup') do
|
|
14
|
+
# archive :my_archive do |archive|
|
|
15
|
+
# archive.add 'path/to/archive'
|
|
16
|
+
# archive.add '/another/path/to/archive'
|
|
17
|
+
# archive.exclude 'path/to/exclude'
|
|
18
|
+
# archive.exclude '/another/path/to/exclude'
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# All paths added using `add` or `exclude` will be expanded to their
|
|
23
|
+
# full paths from the root of the filesystem. Files will be added to
|
|
24
|
+
# the tar archive using these full paths, and their leading `/` will
|
|
25
|
+
# be preserved (using tar's `-P` option).
|
|
26
|
+
#
|
|
27
|
+
# /path/to/pwd/path/to/archive/...
|
|
28
|
+
# /another/path/to/archive/...
|
|
29
|
+
#
|
|
30
|
+
# When a `root` path is given, paths to add/exclude are taken as
|
|
31
|
+
# relative to the `root` path, unless given as absolute paths.
|
|
32
|
+
#
|
|
33
|
+
# Backup::Model.new(:my_backup, 'My Backup') do
|
|
34
|
+
# archive :my_archive do |archive|
|
|
35
|
+
# archive.root '~/my_data'
|
|
36
|
+
# archive.add 'path/to/archive'
|
|
37
|
+
# archive.add '/another/path/to/archive'
|
|
38
|
+
# archive.exclude 'path/to/exclude'
|
|
39
|
+
# archive.exclude '/another/path/to/exclude'
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# This directs `tar` to change directories to the `root` path to create
|
|
44
|
+
# the archive. Unless paths were given as absolute, the paths within the
|
|
45
|
+
# archive will be relative to the `root` path.
|
|
46
|
+
#
|
|
47
|
+
# path/to/archive/...
|
|
48
|
+
# /another/path/to/archive/...
|
|
49
|
+
#
|
|
50
|
+
# For absolute paths added to this archive, the leading `/` will be
|
|
51
|
+
# preserved. Take note that when archives are extracted, leading `/` are
|
|
52
|
+
# stripped by default, so care must be taken when extracting archives with
|
|
53
|
+
# mixed relative/absolute paths.
|
|
54
|
+
def initialize(model, name, &block)
|
|
55
|
+
@model = model
|
|
56
|
+
@name = name.to_s
|
|
57
|
+
@options = {
|
|
58
|
+
:sudo => false,
|
|
59
|
+
:root => false,
|
|
60
|
+
:paths => [],
|
|
61
|
+
:excludes => [],
|
|
62
|
+
:tar_options => ''
|
|
63
|
+
}
|
|
64
|
+
DSL.new(@options).instance_eval(&block)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def perform!
|
|
68
|
+
Logger.info "Creating Archive '#{ name }'..."
|
|
69
|
+
|
|
70
|
+
path = File.join(Config.tmp_path, @model.trigger, 'archives')
|
|
71
|
+
FileUtils.mkdir_p(path)
|
|
72
|
+
|
|
73
|
+
pipeline = Pipeline.new
|
|
74
|
+
with_files_from(paths_to_package) do |files_from|
|
|
75
|
+
pipeline.add(
|
|
76
|
+
"#{ tar_command } #{ tar_options } -cPf -#{ tar_root } " +
|
|
77
|
+
"#{ paths_to_exclude } #{ files_from }",
|
|
78
|
+
tar_success_codes
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
extension = 'tar'
|
|
82
|
+
@model.compressor.compress_with do |command, ext|
|
|
83
|
+
pipeline << command
|
|
84
|
+
extension << ext
|
|
85
|
+
end if @model.compressor
|
|
86
|
+
|
|
87
|
+
pipeline << "#{ utility(:cat) } > " +
|
|
88
|
+
"'#{ File.join(path, "#{ name }.#{ extension }") }'"
|
|
89
|
+
pipeline.run
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if pipeline.success?
|
|
93
|
+
Logger.info "Archive '#{ name }' Complete!"
|
|
94
|
+
else
|
|
95
|
+
raise Error, "Failed to Create Archive '#{ name }'\n" +
|
|
96
|
+
pipeline.error_messages
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def tar_command
|
|
103
|
+
tar = utility(:tar)
|
|
104
|
+
options[:sudo] ? "#{ utility(:sudo) } -n #{ tar }" : tar
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def tar_root
|
|
108
|
+
options[:root] ? " -C '#{ File.expand_path(options[:root]) }'" : ''
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def paths_to_package
|
|
112
|
+
options[:paths].map {|path| prepare_path(path) }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def with_files_from(paths)
|
|
116
|
+
tmpfile = Tempfile.new('backup-archive-paths')
|
|
117
|
+
paths.each {|path| tmpfile.puts path }
|
|
118
|
+
tmpfile.close
|
|
119
|
+
yield "-T '#{ tmpfile.path }'"
|
|
120
|
+
ensure
|
|
121
|
+
tmpfile.delete
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def paths_to_exclude
|
|
125
|
+
options[:excludes].map {|path|
|
|
126
|
+
"--exclude='#{ prepare_path(path) }'"
|
|
127
|
+
}.join(' ')
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def prepare_path(path)
|
|
131
|
+
options[:root] ? path : File.expand_path(path)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def tar_options
|
|
135
|
+
args = options[:tar_options]
|
|
136
|
+
gnu_tar? ? "--ignore-failed-read #{ args }".strip : args
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def tar_success_codes
|
|
140
|
+
gnu_tar? ? [0, 1] : [0]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class DSL
|
|
144
|
+
def initialize(options)
|
|
145
|
+
@options = options
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def use_sudo(val = true)
|
|
149
|
+
@options[:sudo] = val
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def root(path)
|
|
153
|
+
@options[:root] = path
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def add(path)
|
|
157
|
+
@options[:paths] << path
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def exclude(path)
|
|
161
|
+
@options[:excludes] << path
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def tar_options(opts)
|
|
165
|
+
@options[:tar_options] = opts
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
end
|