backupii 0.1.0.pre.alpha.1

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.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +37 -0
  4. data/bin/backupii +5 -0
  5. data/bin/docker_test +24 -0
  6. data/lib/backup/archive.rb +171 -0
  7. data/lib/backup/binder.rb +23 -0
  8. data/lib/backup/cleaner.rb +114 -0
  9. data/lib/backup/cli.rb +376 -0
  10. data/lib/backup/cloud_io/base.rb +40 -0
  11. data/lib/backup/cloud_io/cloud_files.rb +301 -0
  12. data/lib/backup/cloud_io/s3.rb +256 -0
  13. data/lib/backup/compressor/base.rb +34 -0
  14. data/lib/backup/compressor/bzip2.rb +37 -0
  15. data/lib/backup/compressor/custom.rb +51 -0
  16. data/lib/backup/compressor/gzip.rb +76 -0
  17. data/lib/backup/config/dsl.rb +103 -0
  18. data/lib/backup/config/helpers.rb +139 -0
  19. data/lib/backup/config.rb +122 -0
  20. data/lib/backup/database/base.rb +89 -0
  21. data/lib/backup/database/mongodb.rb +189 -0
  22. data/lib/backup/database/mysql.rb +194 -0
  23. data/lib/backup/database/openldap.rb +97 -0
  24. data/lib/backup/database/postgresql.rb +134 -0
  25. data/lib/backup/database/redis.rb +179 -0
  26. data/lib/backup/database/riak.rb +82 -0
  27. data/lib/backup/database/sqlite.rb +57 -0
  28. data/lib/backup/encryptor/base.rb +29 -0
  29. data/lib/backup/encryptor/gpg.rb +745 -0
  30. data/lib/backup/encryptor/open_ssl.rb +76 -0
  31. data/lib/backup/errors.rb +55 -0
  32. data/lib/backup/logger/console.rb +50 -0
  33. data/lib/backup/logger/fog_adapter.rb +27 -0
  34. data/lib/backup/logger/logfile.rb +134 -0
  35. data/lib/backup/logger/syslog.rb +116 -0
  36. data/lib/backup/logger.rb +199 -0
  37. data/lib/backup/model.rb +478 -0
  38. data/lib/backup/notifier/base.rb +128 -0
  39. data/lib/backup/notifier/campfire.rb +63 -0
  40. data/lib/backup/notifier/command.rb +101 -0
  41. data/lib/backup/notifier/datadog.rb +107 -0
  42. data/lib/backup/notifier/flowdock.rb +101 -0
  43. data/lib/backup/notifier/hipchat.rb +118 -0
  44. data/lib/backup/notifier/http_post.rb +116 -0
  45. data/lib/backup/notifier/mail.rb +235 -0
  46. data/lib/backup/notifier/nagios.rb +67 -0
  47. data/lib/backup/notifier/pagerduty.rb +82 -0
  48. data/lib/backup/notifier/prowl.rb +70 -0
  49. data/lib/backup/notifier/pushover.rb +73 -0
  50. data/lib/backup/notifier/ses.rb +126 -0
  51. data/lib/backup/notifier/slack.rb +149 -0
  52. data/lib/backup/notifier/twitter.rb +57 -0
  53. data/lib/backup/notifier/zabbix.rb +62 -0
  54. data/lib/backup/package.rb +53 -0
  55. data/lib/backup/packager.rb +108 -0
  56. data/lib/backup/pipeline.rb +122 -0
  57. data/lib/backup/splitter.rb +75 -0
  58. data/lib/backup/storage/base.rb +72 -0
  59. data/lib/backup/storage/cloud_files.rb +158 -0
  60. data/lib/backup/storage/cycler.rb +73 -0
  61. data/lib/backup/storage/dropbox.rb +208 -0
  62. data/lib/backup/storage/ftp.rb +118 -0
  63. data/lib/backup/storage/local.rb +63 -0
  64. data/lib/backup/storage/qiniu.rb +68 -0
  65. data/lib/backup/storage/rsync.rb +251 -0
  66. data/lib/backup/storage/s3.rb +157 -0
  67. data/lib/backup/storage/scp.rb +67 -0
  68. data/lib/backup/storage/sftp.rb +82 -0
  69. data/lib/backup/syncer/base.rb +70 -0
  70. data/lib/backup/syncer/cloud/base.rb +180 -0
  71. data/lib/backup/syncer/cloud/cloud_files.rb +83 -0
  72. data/lib/backup/syncer/cloud/local_file.rb +99 -0
  73. data/lib/backup/syncer/cloud/s3.rb +118 -0
  74. data/lib/backup/syncer/rsync/base.rb +55 -0
  75. data/lib/backup/syncer/rsync/local.rb +29 -0
  76. data/lib/backup/syncer/rsync/pull.rb +49 -0
  77. data/lib/backup/syncer/rsync/push.rb +206 -0
  78. data/lib/backup/template.rb +45 -0
  79. data/lib/backup/utilities.rb +235 -0
  80. data/lib/backup/version.rb +5 -0
  81. data/lib/backup.rb +141 -0
  82. data/templates/cli/archive +28 -0
  83. data/templates/cli/compressor/bzip2 +4 -0
  84. data/templates/cli/compressor/custom +7 -0
  85. data/templates/cli/compressor/gzip +4 -0
  86. data/templates/cli/config +123 -0
  87. data/templates/cli/databases/mongodb +15 -0
  88. data/templates/cli/databases/mysql +18 -0
  89. data/templates/cli/databases/openldap +24 -0
  90. data/templates/cli/databases/postgresql +16 -0
  91. data/templates/cli/databases/redis +16 -0
  92. data/templates/cli/databases/riak +17 -0
  93. data/templates/cli/databases/sqlite +11 -0
  94. data/templates/cli/encryptor/gpg +27 -0
  95. data/templates/cli/encryptor/openssl +9 -0
  96. data/templates/cli/model +26 -0
  97. data/templates/cli/notifier/zabbix +15 -0
  98. data/templates/cli/notifiers/campfire +12 -0
  99. data/templates/cli/notifiers/command +32 -0
  100. data/templates/cli/notifiers/datadog +57 -0
  101. data/templates/cli/notifiers/flowdock +16 -0
  102. data/templates/cli/notifiers/hipchat +16 -0
  103. data/templates/cli/notifiers/http_post +32 -0
  104. data/templates/cli/notifiers/mail +24 -0
  105. data/templates/cli/notifiers/nagios +13 -0
  106. data/templates/cli/notifiers/pagerduty +12 -0
  107. data/templates/cli/notifiers/prowl +11 -0
  108. data/templates/cli/notifiers/pushover +11 -0
  109. data/templates/cli/notifiers/ses +15 -0
  110. data/templates/cli/notifiers/slack +22 -0
  111. data/templates/cli/notifiers/twitter +13 -0
  112. data/templates/cli/splitter +7 -0
  113. data/templates/cli/storages/cloud_files +11 -0
  114. data/templates/cli/storages/dropbox +20 -0
  115. data/templates/cli/storages/ftp +13 -0
  116. data/templates/cli/storages/local +8 -0
  117. data/templates/cli/storages/qiniu +12 -0
  118. data/templates/cli/storages/rsync +17 -0
  119. data/templates/cli/storages/s3 +16 -0
  120. data/templates/cli/storages/scp +15 -0
  121. data/templates/cli/storages/sftp +15 -0
  122. data/templates/cli/syncers/cloud_files +22 -0
  123. data/templates/cli/syncers/rsync_local +20 -0
  124. data/templates/cli/syncers/rsync_pull +28 -0
  125. data/templates/cli/syncers/rsync_push +28 -0
  126. data/templates/cli/syncers/s3 +27 -0
  127. data/templates/general/links +3 -0
  128. data/templates/general/version.erb +2 -0
  129. data/templates/notifier/mail/failure.erb +16 -0
  130. data/templates/notifier/mail/success.erb +16 -0
  131. data/templates/notifier/mail/warning.erb +16 -0
  132. data/templates/storage/dropbox/authorization_url.erb +6 -0
  133. data/templates/storage/dropbox/authorized.erb +4 -0
  134. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  135. metadata +507 -0
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ module Database
5
+ class MongoDB < Base
6
+ class Error < Backup::Error; end
7
+
8
+ ##
9
+ # Name of the database that needs to get dumped
10
+ attr_accessor :name
11
+
12
+ ##
13
+ # Credentials for the specified database
14
+ attr_accessor :username, :password, :authdb
15
+
16
+ ##
17
+ # Connectivity options
18
+ attr_accessor :host, :port
19
+
20
+ ##
21
+ # IPv6 support (disabled by default)
22
+ attr_accessor :ipv6
23
+
24
+ ##
25
+ # Collections to dump, collections that aren't specified won't get dumped
26
+ attr_accessor :only_collections
27
+
28
+ ##
29
+ # Additional "mongodump" options
30
+ attr_accessor :additional_options
31
+
32
+ ##
33
+ # Forces mongod to flush all pending write operations to the disk and
34
+ # locks the entire mongod instance to prevent additional writes until the
35
+ # dump is complete.
36
+ #
37
+ # Note that if Profiling is enabled, this will disable it and will not
38
+ # re-enable it after the dump is complete.
39
+ attr_accessor :lock
40
+
41
+ ##
42
+ # Creates a dump of the database that includes an oplog, to create a
43
+ # point-in-time snapshot of the state of a mongod instance.
44
+ #
45
+ # If this option is used, you would not use the `lock` option.
46
+ #
47
+ # This will only work against nodes that maintain a oplog.
48
+ # This includes all members of a replica set, as well as master nodes in
49
+ # master/slave replication deployments.
50
+ attr_accessor :oplog
51
+
52
+ def initialize(model, database_id = nil, &block)
53
+ super
54
+ instance_eval(&block) if block_given?
55
+ end
56
+
57
+ def perform!
58
+ super
59
+
60
+ lock_database if @lock
61
+ dump!
62
+ package!
63
+ ensure
64
+ unlock_database if @lock
65
+ end
66
+
67
+ private
68
+
69
+ ##
70
+ # Performs all required mongodump commands, dumping the output files
71
+ # into the +dump_packaging_path+ directory for packaging.
72
+ def dump!
73
+ FileUtils.mkdir_p dump_packaging_path
74
+
75
+ collections = Array(only_collections)
76
+ if collections.empty?
77
+ run(mongodump)
78
+ else
79
+ collections.each do |collection|
80
+ run("#{mongodump} --collection='#{collection}'")
81
+ end
82
+ end
83
+ end
84
+
85
+ ##
86
+ # Creates a tar archive of the +dump_packaging_path+ directory
87
+ # and stores it in the +dump_path+ using +dump_filename+.
88
+ #
89
+ # <trigger>/databases/MongoDB[-<database_id>].tar[.gz]
90
+ #
91
+ # If successful, +dump_packaging_path+ is removed.
92
+ def package!
93
+ pipeline = Pipeline.new
94
+ dump_ext = "tar".dup
95
+
96
+ pipeline << "#{utility(:tar)} -cf - " \
97
+ "-C '#{dump_path}' '#{dump_filename}'"
98
+
99
+ if model.compressor
100
+ model.compressor.compress_with do |command, ext|
101
+ pipeline << command
102
+ dump_ext << ext
103
+ end
104
+ end
105
+
106
+ pipeline << "#{utility(:cat)} > " \
107
+ "'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
108
+
109
+ pipeline.run
110
+ if pipeline.success?
111
+ FileUtils.rm_rf dump_packaging_path
112
+ log!(:finished)
113
+ else
114
+ raise Error, "Dump Failed!\n#{pipeline.error_messages}"
115
+ end
116
+ end
117
+
118
+ def dump_packaging_path
119
+ File.join(dump_path, dump_filename)
120
+ end
121
+
122
+ def mongodump
123
+ "#{utility(:mongodump)} #{name_option} #{credential_options} " \
124
+ "#{connectivity_options} #{ipv6_option} #{oplog_option} " \
125
+ "#{user_options} --out='#{dump_packaging_path}'"
126
+ end
127
+
128
+ def name_option
129
+ return unless name
130
+
131
+ "--db='#{name}'"
132
+ end
133
+
134
+ def credential_options
135
+ opts = []
136
+ opts << "--username='#{username}'" if username
137
+ opts << "--password='#{password}'" if password
138
+ opts << "--authenticationDatabase='#{authdb}'" if authdb
139
+ opts.join(" ")
140
+ end
141
+
142
+ def connectivity_options
143
+ opts = []
144
+ opts << "--host='#{host}'" if host
145
+ opts << "--port='#{port}'" if port
146
+ opts.join(" ")
147
+ end
148
+
149
+ def ipv6_option
150
+ "--ipv6" if ipv6
151
+ end
152
+
153
+ def oplog_option
154
+ "--oplog" if oplog
155
+ end
156
+
157
+ def user_options
158
+ Array(additional_options).join(" ")
159
+ end
160
+
161
+ def lock_database
162
+ lock_command = <<-EOS.gsub(%r{^ +}, "")
163
+ echo 'use admin
164
+ db.setProfilingLevel(0)
165
+ db.fsyncLock()' | #{mongo_shell}
166
+ EOS
167
+
168
+ run(lock_command)
169
+ end
170
+
171
+ def unlock_database
172
+ unlock_command = <<-EOS.gsub(%r{^ +}, "")
173
+ echo 'use admin
174
+ db.fsyncUnlock()' | #{mongo_shell}
175
+ EOS
176
+
177
+ run(unlock_command)
178
+ end
179
+
180
+ def mongo_shell
181
+ cmd = "#{utility(:mongo)} #{connectivity_options}".rstrip
182
+ cmd << " #{credential_options}".rstrip
183
+ cmd << " #{ipv6_option}".rstrip
184
+ cmd << " '#{name}'" if name
185
+ cmd
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ module Database
5
+ class MySQL < Base
6
+ class Error < Backup::Error; end
7
+
8
+ ##
9
+ # Name of the database that needs to get dumped
10
+ # To dump all databases, set this to `:all` or leave blank.
11
+ attr_accessor :name
12
+
13
+ ##
14
+ # Credentials for the specified database
15
+ attr_accessor :username, :password
16
+
17
+ ##
18
+ # Connectivity options
19
+ attr_accessor :host, :port, :socket
20
+
21
+ ##
22
+ # Tables to skip while dumping the database
23
+ #
24
+ # If `name` is set to :all (or not specified), these must include
25
+ # a database name. e.g. 'name.table'.
26
+ # If `name` is given, these may simply be table names.
27
+ attr_accessor :skip_tables
28
+
29
+ ##
30
+ # Tables to dump. This in only valid if `name` is specified.
31
+ # If none are given, the entire database will be dumped.
32
+ attr_accessor :only_tables
33
+
34
+ ##
35
+ # Additional "mysqldump" or "innobackupex (backup creation)" options
36
+ attr_accessor :additional_options
37
+
38
+ ##
39
+ # Additional innobackupex log preparation phase ("apply-logs") options
40
+ attr_accessor :prepare_options
41
+
42
+ ##
43
+ # Default is :mysqldump (which is built in MySQL and generates
44
+ # a textual SQL file), but can be changed to :innobackupex, which
45
+ # has more feasible restore times for large databases.
46
+ # See: http://www.percona.com/doc/percona-xtrabackup/
47
+ attr_accessor :backup_engine
48
+
49
+ ##
50
+ # If true (which is the default behaviour), the backup will be prepared
51
+ # after it has been successfuly created. This option is only valid if
52
+ # :backup_engine is set to :innobackupex.
53
+ attr_accessor :prepare_backup
54
+
55
+ ##
56
+ # If set the backup engine command block is executed as the given user
57
+ attr_accessor :sudo_user
58
+
59
+ ##
60
+ # If set, do not suppress innobackupdb output (useful for debugging)
61
+ attr_accessor :verbose
62
+
63
+ def initialize(model, database_id = nil, &block)
64
+ super
65
+ instance_eval(&block) if block_given?
66
+
67
+ @name ||= :all
68
+ @backup_engine ||= :mysqldump
69
+ @prepare_backup = true if @prepare_backup.nil?
70
+ end
71
+
72
+ ##
73
+ # Performs the mysqldump or innobackupex command and outputs
74
+ # the dump file in the +dump_path+ using +dump_filename+.
75
+ #
76
+ # <trigger>/databases/MySQL[-<database_id>].[sql|tar][.gz]
77
+ def perform!
78
+ super
79
+
80
+ pipeline = Pipeline.new
81
+ dump_ext = (sql_backup? ? "sql" : "tar").dup
82
+
83
+ pipeline << sudo_option(sql_backup? ? mysqldump : innobackupex)
84
+
85
+ if model.compressor
86
+ model.compressor.compress_with do |command, ext|
87
+ pipeline << command
88
+ dump_ext << ext
89
+ end
90
+ end
91
+
92
+ pipeline << "#{utility(:cat)} > " \
93
+ "'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
94
+
95
+ pipeline.run
96
+ if pipeline.success?
97
+ log!(:finished)
98
+ else
99
+ raise Error, "Dump Failed!\n#{pipeline.error_messages}"
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def mysqldump
106
+ "#{utility(:mysqldump)} #{user_options} #{credential_options} " \
107
+ "#{connectivity_options} #{name_option} " \
108
+ "#{tables_to_dump} #{tables_to_skip}"
109
+ end
110
+
111
+ def credential_options
112
+ opts = []
113
+ opts << "--user=#{Shellwords.escape(username)}" if username
114
+ opts << "--password=#{Shellwords.escape(password)}" if password
115
+ opts.join(" ")
116
+ end
117
+
118
+ def connectivity_options
119
+ return "--socket='#{socket}'" if socket
120
+
121
+ opts = []
122
+ opts << "--host='#{host}'" if host
123
+ opts << "--port='#{port}'" if port
124
+ opts.join(" ")
125
+ end
126
+
127
+ def user_options
128
+ Array(additional_options).join(" ")
129
+ end
130
+
131
+ def user_prepare_options
132
+ Array(prepare_options).join(" ")
133
+ end
134
+
135
+ def name_option
136
+ dump_all? ? "--all-databases" : name
137
+ end
138
+
139
+ def tables_to_dump
140
+ Array(only_tables).join(" ") unless dump_all?
141
+ end
142
+
143
+ def tables_to_skip
144
+ Array(skip_tables).map do |table|
145
+ table = dump_all? || table["."] ? table : "#{name}.#{table}"
146
+ "--ignore-table='#{table}'"
147
+ end.join(" ")
148
+ end
149
+
150
+ def dump_all?
151
+ name == :all
152
+ end
153
+
154
+ def sql_backup?
155
+ backup_engine.to_sym == :mysqldump
156
+ end
157
+
158
+ def innobackupex
159
+ # Creation phase
160
+ "#{utility(:innobackupex)} #{credential_options} " \
161
+ "#{connectivity_options} #{user_options} " \
162
+ "--no-timestamp #{temp_dir} #{quiet_option} && " +
163
+ innobackupex_prepare +
164
+ # Move files to tar-ed stream on stdout
165
+ "#{utility(:tar)} --remove-files -cf - " \
166
+ "-C #{File.dirname(temp_dir)} #{File.basename(temp_dir)}"
167
+ end
168
+
169
+ def innobackupex_prepare
170
+ return "" unless @prepare_backup
171
+
172
+ # Log applying phase (prepare for restore)
173
+ "#{utility(:innobackupex)} --apply-log #{temp_dir} " \
174
+ "#{user_prepare_options} #{quiet_option} && "
175
+ end
176
+
177
+ def sudo_option(command_block)
178
+ return command_block unless sudo_user
179
+
180
+ "sudo -s -u #{sudo_user} -- <<END_OF_SUDO\n" \
181
+ "#{command_block}\n" \
182
+ "END_OF_SUDO\n"
183
+ end
184
+
185
+ def quiet_option
186
+ verbose ? "" : " 2> /dev/null "
187
+ end
188
+
189
+ def temp_dir
190
+ File.join(dump_path, "#{dump_filename}.bkpdir")
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ module Database
5
+ class OpenLDAP < Base
6
+ class Error < Backup::Error; end
7
+
8
+ ##
9
+ # Name of the ldap backup
10
+ attr_accessor :name
11
+
12
+ ##
13
+ # run slapcat under sudo if needed make sure to set SUID on a file, to let
14
+ # you run the file with permissions of file owner
15
+ #
16
+ # eg. sudo chmod u+s /usr/sbin/slapcat
17
+ attr_accessor :use_sudo
18
+
19
+ ##
20
+ # Stores the location of the slapd.conf or slapcat confdir
21
+ attr_accessor :slapcat_conf
22
+
23
+ ##
24
+ # Additional slapcat options
25
+ attr_accessor :slapcat_args
26
+
27
+ ##
28
+ # Path to slapcat utility (optional)
29
+ attr_accessor :slapcat_utility
30
+
31
+ ##
32
+ # Takes the name of the archive and the configuration block
33
+ def initialize(model, database_id = nil, &block)
34
+ super
35
+ instance_eval(&block) if block_given?
36
+
37
+ @name ||= "ldap_backup"
38
+ @use_sudo ||= false
39
+ @slapcat_args ||= []
40
+ @slapcat_utility ||= utility(:slapcat)
41
+ @slapcat_conf ||= "/etc/ldap/slapd.d"
42
+ end
43
+
44
+ ##
45
+ # Performs the slapcat command and outputs the
46
+ # data to the specified path based on the 'trigger'
47
+ def perform!
48
+ super
49
+
50
+ pipeline = Pipeline.new
51
+ dump_ext = "ldif".dup
52
+
53
+ pipeline << slapcat
54
+ if @model.compressor
55
+ @model.compressor.compress_with do |command, ext|
56
+ pipeline << command
57
+ dump_ext << ext
58
+ end
59
+ end
60
+
61
+ pipeline << "#{utility(:cat)} > " \
62
+ "'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
63
+
64
+ pipeline.run
65
+ if pipeline.success?
66
+ log!(:finished)
67
+ else
68
+ raise Error, "Dump Failed!\n" + pipeline.error_messages
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ ##
75
+ # Builds the full slapcat string based on all attributes
76
+ def slapcat
77
+ command = "#{slapcat_utility} #{slapcat_conf_option} " \
78
+ "#{slapcat_conf} #{user_options}".dup
79
+ command.prepend("sudo ") if use_sudo
80
+ command
81
+ end
82
+
83
+ ##
84
+ # Uses different slapcat switch depending on confdir or conffile set
85
+ def slapcat_conf_option
86
+ @slapcat_conf.include?(".d") ? "-F" : "-f"
87
+ end
88
+
89
+ ##
90
+ # Builds a compatible string for the additional options
91
+ # specified by the user
92
+ def user_options
93
+ slapcat_args.join(" ")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ module Database
5
+ class PostgreSQL < Base
6
+ class Error < Backup::Error; end
7
+
8
+ ##
9
+ # Name of the database that needs to get dumped.
10
+ # To dump all databases, set this to `:all` or leave blank.
11
+ # +username+ must be a PostgreSQL superuser to run `pg_dumpall`.
12
+ attr_accessor :name
13
+
14
+ ##
15
+ # Credentials for the specified database
16
+ attr_accessor :username, :password
17
+
18
+ ##
19
+ # If set the pg_dump(all) command is executed as the given user
20
+ attr_accessor :sudo_user
21
+
22
+ ##
23
+ # Connectivity options
24
+ attr_accessor :host, :port, :socket
25
+
26
+ ##
27
+ # Tables to skip while dumping the database.
28
+ # If `name` is set to :all (or not specified), these are ignored.
29
+ attr_accessor :skip_tables
30
+
31
+ ##
32
+ # Tables to dump. This in only valid if `name` is specified.
33
+ # If none are given, the entire database will be dumped.
34
+ attr_accessor :only_tables
35
+
36
+ ##
37
+ # Additional "pg_dump" or "pg_dumpall" options
38
+ attr_accessor :additional_options
39
+
40
+ def initialize(model, database_id = nil, &block)
41
+ super
42
+ instance_eval(&block) if block_given?
43
+
44
+ @name ||= :all
45
+ end
46
+
47
+ ##
48
+ # Performs the pgdump command and outputs the dump file
49
+ # in the +dump_path+ using +dump_filename+.
50
+ #
51
+ # <trigger>/databases/PostgreSQL[-<database_id>].sql[.gz]
52
+ def perform!
53
+ super
54
+
55
+ pipeline = Pipeline.new
56
+ dump_ext = "sql".dup
57
+
58
+ pipeline << (dump_all? ? pgdumpall : pgdump)
59
+
60
+ if model.compressor
61
+ model.compressor.compress_with do |command, ext|
62
+ pipeline << command
63
+ dump_ext << ext
64
+ end
65
+ end
66
+
67
+ pipeline << "#{utility(:cat)} > " \
68
+ "'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
69
+
70
+ pipeline.run
71
+ if pipeline.success?
72
+ log!(:finished)
73
+ else
74
+ raise Error, "Dump Failed!\n" + pipeline.error_messages
75
+ end
76
+ end
77
+
78
+ def pgdump
79
+ password_option.to_s +
80
+ sudo_option.to_s +
81
+ "#{utility(:pg_dump)} #{username_option} #{connectivity_options} " \
82
+ "#{user_options} #{tables_to_dump} #{tables_to_skip} #{name}"
83
+ end
84
+
85
+ def pgdumpall
86
+ password_option.to_s +
87
+ sudo_option.to_s +
88
+ "#{utility(:pg_dumpall)} #{username_option} " \
89
+ "#{connectivity_options} #{user_options}"
90
+ end
91
+
92
+ def password_option
93
+ "PGPASSWORD=#{Shellwords.escape(password)} " if password
94
+ end
95
+
96
+ def sudo_option
97
+ "#{utility(:sudo)} -n -H -u #{sudo_user} " if sudo_user
98
+ end
99
+
100
+ def username_option
101
+ "--username=#{Shellwords.escape(username)}" if username
102
+ end
103
+
104
+ def connectivity_options
105
+ return "--host='#{socket}'" if socket
106
+
107
+ opts = []
108
+ opts << "--host='#{host}'" if host
109
+ opts << "--port='#{port}'" if port
110
+ opts.join(" ")
111
+ end
112
+
113
+ def user_options
114
+ Array(additional_options).join(" ")
115
+ end
116
+
117
+ def tables_to_dump
118
+ Array(only_tables).map do |table|
119
+ "--table='#{table}'"
120
+ end.join(" ")
121
+ end
122
+
123
+ def tables_to_skip
124
+ Array(skip_tables).map do |table|
125
+ "--exclude-table='#{table}'"
126
+ end.join(" ")
127
+ end
128
+
129
+ def dump_all?
130
+ name == :all
131
+ end
132
+ end
133
+ end
134
+ end