chef_backup 0.0.1.dev.4 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/chef_backup.gemspec +1 -1
- data/lib/chef_backup/config.rb +15 -5
- data/lib/chef_backup/helpers.rb +117 -27
- data/lib/chef_backup/runner.rb +10 -3
- data/lib/chef_backup/strategy/backup/tar.rb +72 -32
- data/lib/chef_backup/strategy/restore/tar.rb +14 -10
- data/lib/chef_backup/version.rb +1 -1
- data/spec/spec_helper.rb +0 -5
- data/spec/unit/strategy/backup/tar_spec.rb +41 -8
- data/spec/unit/strategy/restore/tar_spec.rb +20 -3
- metadata +9 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3aaeca0a04fa4fe4ee8443b47d5f9295929d201d
|
4
|
+
data.tar.gz: 82f06bbc30bff3a57c235d98012f0a251498af9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 688f33e0046368ac2c35dcf7dce9ae9f474cf5e8d8628651c105af4c709769fe7728e5e4a8fd66d530f0e2ad82577039bd42874ffdb34b4a168b563045460b1f
|
7
|
+
data.tar.gz: 3c965dbc203fd45876c38d051cc2427ba67e9a8a97c38db7b947f85d2d4e277de620a06dd0fa9a7bf29f04eec327787006e17679e2b6140e84445f36e1e9dac0
|
data/chef_backup.gemspec
CHANGED
@@ -28,6 +28,6 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
29
29
|
spec.add_development_dependency 'guard-rspec'
|
30
30
|
spec.add_development_dependency 'pry-rescue'
|
31
|
-
spec.add_development_dependency 'rubocop', '
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.37.2'
|
32
32
|
spec.add_development_dependency 'simplecov'
|
33
33
|
end
|
data/lib/chef_backup/config.rb
CHANGED
@@ -7,11 +7,16 @@ module ChefBackup
|
|
7
7
|
class Config
|
8
8
|
extend Forwardable
|
9
9
|
|
10
|
+
DEFAULT_BASE = 'private_chef'.freeze
|
10
11
|
DEFAULT_CONFIG = {
|
11
12
|
'backup' => {
|
12
13
|
'always_dump_db' => true,
|
13
14
|
'strategy' => 'none',
|
14
|
-
'export_dir' => '/var/opt/chef-backup'
|
15
|
+
'export_dir' => '/var/opt/chef-backup',
|
16
|
+
'project_name' => 'opscode',
|
17
|
+
'ctl-command' => 'chef-server-ctl',
|
18
|
+
'running_filepath' => '/etc/opscode/chef-server-running.json',
|
19
|
+
'database_name' => 'opscode_chef'
|
15
20
|
}
|
16
21
|
}.freeze
|
17
22
|
|
@@ -45,13 +50,18 @@ module ChefBackup
|
|
45
50
|
# @param config [Hash] a Hash of the private-chef-running.json
|
46
51
|
#
|
47
52
|
def initialize(config = {})
|
48
|
-
config['
|
49
|
-
config['
|
50
|
-
config[
|
51
|
-
|
53
|
+
config['config_base'] ||= DEFAULT_BASE
|
54
|
+
base = config['config_base']
|
55
|
+
config[base] ||= {}
|
56
|
+
config[base]['backup'] ||= {}
|
57
|
+
config[base]['backup'] = DEFAULT_CONFIG['backup'].merge(config[base]['backup'])
|
52
58
|
@config = config
|
53
59
|
end
|
54
60
|
|
61
|
+
def to_hash
|
62
|
+
@config
|
63
|
+
end
|
64
|
+
|
55
65
|
def_delegators :@config, :[], :[]=
|
56
66
|
end
|
57
67
|
end
|
data/lib/chef_backup/helpers.rb
CHANGED
@@ -9,23 +9,62 @@ module ChefBackup
|
|
9
9
|
module Helpers
|
10
10
|
# rubocop:enable IndentationWidth
|
11
11
|
|
12
|
-
SERVER_ADD_ONS =
|
13
|
-
opscode-manage
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
SERVER_ADD_ONS = {
|
13
|
+
'opscode-manage' => {
|
14
|
+
'config_file' => '/etc/opscode-manage/manage.rb',
|
15
|
+
'ctl_command' => 'opscode-manage-ctl'
|
16
|
+
},
|
17
|
+
'opscode-reporting' => {
|
18
|
+
'config_file' => '/etc/opscode-reporting/opscode-reporting.rb',
|
19
|
+
'ctl_command' => 'opscode-reporting-ctl'
|
20
|
+
},
|
21
|
+
'opscode-push-jobs-server' => {
|
22
|
+
'config_file' => '/etc/opscode-push-jobs-server/opscode-push-jobs-server.rb',
|
23
|
+
'ctl_command' => 'opscode-push-jobs-server-ctl'
|
24
|
+
},
|
25
|
+
'opscode-analytics' => {
|
26
|
+
'config_file' => '/etc/opscode-analytics/opscode-analytics.rb',
|
27
|
+
'ctl_command' => 'opscode-analytics-ctl'
|
28
|
+
},
|
29
|
+
'chef-ha' => {
|
30
|
+
'config_file' => 'etc/opscode/chef-server.rb'
|
31
|
+
},
|
32
|
+
'chef-sync' => {
|
33
|
+
'config_file' => '/etc/chef-sync/chef-sync.rb',
|
34
|
+
'ctl_command' => 'chef-sync-ctl'
|
35
|
+
},
|
36
|
+
'chef-marketplace' => {
|
37
|
+
'config_file' => '/etc/chef-marketplace/marketplace.rb',
|
38
|
+
'ctl_command' => 'chef-marketplace-ctl'
|
39
|
+
}
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
DEFAULT_PG_OPTIONS = '-c statement_timeout=3600000'.freeze
|
24
43
|
|
25
44
|
def config
|
26
45
|
ChefBackup::Config
|
27
46
|
end
|
28
47
|
|
48
|
+
def config_base
|
49
|
+
ChefBackup::Config['config_base']
|
50
|
+
end
|
51
|
+
|
52
|
+
def service_config
|
53
|
+
ChefBackup::Config[config_base]
|
54
|
+
end
|
55
|
+
|
56
|
+
def ctl_command
|
57
|
+
service_config['backup']['ctl-command']
|
58
|
+
end
|
59
|
+
|
60
|
+
def running_filepath
|
61
|
+
service_config['backup']['running_filepath']
|
62
|
+
end
|
63
|
+
|
64
|
+
def database_name
|
65
|
+
service_config['backup']['database_name']
|
66
|
+
end
|
67
|
+
|
29
68
|
def log(message, level = :info)
|
30
69
|
ChefBackup::Logger.logger.log(message, level)
|
31
70
|
end
|
@@ -38,7 +77,7 @@ module Helpers
|
|
38
77
|
# @return [TrueClass, FalseClass]
|
39
78
|
#
|
40
79
|
def ensure_file!(file, exception, message)
|
41
|
-
File.exist?(file) ? true :
|
80
|
+
File.exist?(file) ? true : raise(exception, message)
|
42
81
|
end
|
43
82
|
|
44
83
|
def shell_out(*command)
|
@@ -54,8 +93,32 @@ module Helpers
|
|
54
93
|
cmd
|
55
94
|
end
|
56
95
|
|
96
|
+
def project_name
|
97
|
+
service_config['backup']['project_name']
|
98
|
+
end
|
99
|
+
|
100
|
+
def base_install_dir
|
101
|
+
"/opt/#{project_name}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def base_config_dir
|
105
|
+
"/etc/#{project_name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def chpst
|
109
|
+
"#{base_install_dir}/embedded/bin/chpst"
|
110
|
+
end
|
111
|
+
|
112
|
+
def pgsql
|
113
|
+
"#{base_install_dir}/embedded/bin/psql"
|
114
|
+
end
|
115
|
+
|
116
|
+
def pg_options
|
117
|
+
config['pg_options'] || DEFAULT_PG_OPTIONS
|
118
|
+
end
|
119
|
+
|
57
120
|
def all_services
|
58
|
-
Dir[
|
121
|
+
Dir["#{base_install_dir}/sv/*"].map { |f| File.basename(f) }.sort
|
59
122
|
end
|
60
123
|
|
61
124
|
def enabled_services
|
@@ -67,16 +130,16 @@ module Helpers
|
|
67
130
|
end
|
68
131
|
|
69
132
|
def service_enabled?(service)
|
70
|
-
File.symlink?("/
|
133
|
+
File.symlink?("#{base_install_dir}/service/#{service}")
|
71
134
|
end
|
72
135
|
|
73
136
|
def stop_service(service)
|
74
|
-
res = shell_out("
|
137
|
+
res = shell_out("#{ctl_command} stop #{service}")
|
75
138
|
res
|
76
139
|
end
|
77
140
|
|
78
141
|
def start_service(service)
|
79
|
-
res = shell_out("
|
142
|
+
res = shell_out("#{ctl_command} start #{service}")
|
80
143
|
res
|
81
144
|
end
|
82
145
|
|
@@ -92,32 +155,55 @@ module Helpers
|
|
92
155
|
enabled_services.each { |sv| start_service(sv) }
|
93
156
|
end
|
94
157
|
|
95
|
-
def
|
96
|
-
|
158
|
+
def restart_chef_server
|
159
|
+
shell_out("#{ctl_command} restart #{service}")
|
97
160
|
end
|
98
161
|
|
99
|
-
def
|
100
|
-
|
162
|
+
def reconfigure_add_ons
|
163
|
+
enabled_addons.each do |_name, config|
|
164
|
+
shell_out("#{config['ctl_command']} reconfigure") if config.key?('ctl_command')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def restart_add_ons
|
169
|
+
enabled_addons.each do |_name, config|
|
170
|
+
shell_out("#{config['ctl_command']} restart") if config.key?('ctl_command')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def reconfigure_marketplace
|
175
|
+
log 'Setting up Chef Marketplace'
|
176
|
+
shell_out('chef-marketplace-ctl reconfigure')
|
177
|
+
end
|
178
|
+
|
179
|
+
def enabled_addons
|
180
|
+
SERVER_ADD_ONS.select do |_name, config|
|
181
|
+
begin
|
182
|
+
File.directory?(File.dirname(config['config_file']))
|
183
|
+
rescue
|
184
|
+
false
|
185
|
+
end
|
186
|
+
end
|
101
187
|
end
|
102
188
|
|
103
189
|
def strategy
|
104
|
-
|
190
|
+
service_config['backup']['strategy']
|
105
191
|
end
|
106
192
|
|
107
193
|
def topology
|
108
|
-
|
194
|
+
service_config['topology']
|
109
195
|
end
|
110
196
|
|
111
197
|
def frontend?
|
112
|
-
|
198
|
+
service_config['role'] == 'frontend'
|
113
199
|
end
|
114
200
|
|
115
201
|
def backend?
|
116
|
-
|
202
|
+
service_config['role'] =~ /backend|standalone/
|
117
203
|
end
|
118
204
|
|
119
205
|
def online?
|
120
|
-
|
206
|
+
service_config['backup']['mode'] == 'online'
|
121
207
|
end
|
122
208
|
|
123
209
|
def ha?
|
@@ -132,10 +218,14 @@ module Helpers
|
|
132
218
|
topology == 'standalone'
|
133
219
|
end
|
134
220
|
|
221
|
+
def marketplace?
|
222
|
+
shell_out('which chef-marketplace-ctl').exitstatus == 0
|
223
|
+
end
|
224
|
+
|
135
225
|
def tmp_dir
|
136
226
|
@tmp_dir ||= begin
|
137
227
|
dir = safe_key { config['tmp_dir'] } ||
|
138
|
-
safe_key {
|
228
|
+
safe_key { service_config['backup']['tmp_dir'] }
|
139
229
|
if dir
|
140
230
|
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
141
231
|
dir
|
data/lib/chef_backup/runner.rb
CHANGED
@@ -17,7 +17,7 @@ module ChefBackup
|
|
17
17
|
#
|
18
18
|
def initialize(running_config)
|
19
19
|
ChefBackup::Config.config = running_config
|
20
|
-
ChefBackup::Logger.logger(
|
20
|
+
ChefBackup::Logger.logger(service_config['backup']['logfile'] || nil)
|
21
21
|
end
|
22
22
|
|
23
23
|
#
|
@@ -28,6 +28,13 @@ module ChefBackup
|
|
28
28
|
@backup.backup
|
29
29
|
end
|
30
30
|
|
31
|
+
#
|
32
|
+
# @return [ChefBackup::Config]
|
33
|
+
#
|
34
|
+
def config
|
35
|
+
ChefBackup::Config.config
|
36
|
+
end
|
37
|
+
|
31
38
|
#
|
32
39
|
# @return [TrueClass, FalseClass] Execute Chef Server restore
|
33
40
|
#
|
@@ -40,7 +47,7 @@ module ChefBackup
|
|
40
47
|
# @return [String] String name of the configured backup strategy
|
41
48
|
#
|
42
49
|
def backup_strategy
|
43
|
-
|
50
|
+
service_config['backup']['strategy']
|
44
51
|
end
|
45
52
|
|
46
53
|
#
|
@@ -62,7 +69,7 @@ module ChefBackup
|
|
62
69
|
elsif ebs_snapshot?
|
63
70
|
'ebs'
|
64
71
|
else
|
65
|
-
|
72
|
+
raise InvalidStrategy, "#{restore_param} is not a valid backup"
|
66
73
|
end
|
67
74
|
end
|
68
75
|
end
|
@@ -27,8 +27,8 @@ class TarBackup
|
|
27
27
|
def export_dir
|
28
28
|
@export_dir ||= begin
|
29
29
|
dir =
|
30
|
-
if
|
31
|
-
|
30
|
+
if service_config['backup']['export_dir']
|
31
|
+
service_config['backup']['export_dir']
|
32
32
|
else
|
33
33
|
msg = ["backup['export_dir'] has not been set.",
|
34
34
|
'defaulting to: /var/opt/chef-backups'].join(' ')
|
@@ -47,24 +47,38 @@ class TarBackup
|
|
47
47
|
#
|
48
48
|
def dump_db
|
49
49
|
return true unless pg_dump?
|
50
|
-
|
50
|
+
if external_pg?
|
51
|
+
log('Cannot backup external postgresql', :warn)
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
pg_user = service_config['postgresql']['username']
|
51
55
|
sql_file = "#{tmp_dir}/chef_backup-#{backup_time}.sql"
|
52
|
-
cmd = [
|
56
|
+
cmd = [chpst,
|
53
57
|
"-u #{pg_user}",
|
54
|
-
|
58
|
+
pg_dumpall,
|
55
59
|
"> #{sql_file}"
|
56
60
|
].join(' ')
|
57
61
|
log "Dumping Postgresql database to #{sql_file}"
|
58
|
-
shell_out!(cmd)
|
62
|
+
shell_out!(cmd, env: ["PGOPTIONS=#{pg_options}"])
|
59
63
|
data_map.services['postgresql']['pg_dump_success'] = true
|
60
64
|
data_map.services['postgresql']['username'] = pg_user
|
61
65
|
true
|
62
66
|
end
|
63
67
|
|
68
|
+
def chpst
|
69
|
+
"#{base_install_dir}/embedded/bin/chpst"
|
70
|
+
end
|
71
|
+
|
72
|
+
def pg_dumpall
|
73
|
+
"#{base_install_dir}/embedded/bin/pg_dumpall"
|
74
|
+
end
|
75
|
+
|
64
76
|
def populate_data_map
|
65
|
-
|
66
|
-
|
67
|
-
|
77
|
+
unless config_only?
|
78
|
+
stateful_services.each do |service|
|
79
|
+
next unless service_config.key?(service)
|
80
|
+
data_map.add_service(service, service_config[service]['data_dir'])
|
81
|
+
end
|
68
82
|
end
|
69
83
|
|
70
84
|
config_directories.each do |config|
|
@@ -72,14 +86,14 @@ class TarBackup
|
|
72
86
|
end
|
73
87
|
|
74
88
|
# Don't forget the upgrades!
|
75
|
-
if
|
76
|
-
data_map.add_service('upgrades',
|
89
|
+
if service_config.key?('upgrades')
|
90
|
+
data_map.add_service('upgrades', service_config['upgrades']['dir'])
|
77
91
|
end
|
78
92
|
|
79
|
-
if ha?
|
80
|
-
data_map.add_service('keepalived',
|
81
|
-
data_map.add_ha_info('provider',
|
82
|
-
data_map.add_ha_info('path',
|
93
|
+
if ha? && !config_only?
|
94
|
+
data_map.add_service('keepalived', service_config['keepalived']['dir'])
|
95
|
+
data_map.add_ha_info('provider', service_config['ha']['provider'])
|
96
|
+
data_map.add_ha_info('path', service_config['ha']['path'])
|
83
97
|
end
|
84
98
|
end
|
85
99
|
|
@@ -94,22 +108,25 @@ class TarBackup
|
|
94
108
|
end
|
95
109
|
end
|
96
110
|
|
111
|
+
DEFAULT_STATEFUL_SERVICES = %w(rabbitmq
|
112
|
+
opscode-solr4
|
113
|
+
elasticsearch
|
114
|
+
redis_lb
|
115
|
+
postgresql
|
116
|
+
bookshelf).freeze
|
117
|
+
|
97
118
|
def stateful_services
|
98
|
-
if
|
119
|
+
if service_config.key?('drbd') && service_config['drbd']['enable'] == true
|
99
120
|
['drbd']
|
100
121
|
else
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
redis_lb
|
105
|
-
postgresql
|
106
|
-
bookshelf
|
107
|
-
)
|
122
|
+
DEFAULT_STATEFUL_SERVICES.select do |service|
|
123
|
+
service_enabled?(service)
|
124
|
+
end
|
108
125
|
end
|
109
126
|
end
|
110
127
|
|
111
128
|
def config_directories
|
112
|
-
|
129
|
+
[project_name] + enabled_addons.keys
|
113
130
|
end
|
114
131
|
|
115
132
|
# The data_map is a working record of all of the data that is backed up.
|
@@ -123,25 +140,27 @@ class TarBackup
|
|
123
140
|
|
124
141
|
def not_implemented
|
125
142
|
msg = "#{caller[0].split[1]} is not implemented for this strategy"
|
126
|
-
|
143
|
+
raise NotImplementedError, msg
|
127
144
|
end
|
128
145
|
|
129
146
|
def backup
|
130
|
-
log
|
147
|
+
log "Starting Chef Server backup #{config_only? ? '(config only)' : ''}"
|
131
148
|
populate_data_map
|
132
|
-
|
149
|
+
stopped = false
|
150
|
+
if backend? && !config_only?
|
133
151
|
if !online?
|
134
152
|
ask_to_go_offline unless offline_permission_granted?
|
135
153
|
stop_chef_server(except: [:keepalived, :postgresql])
|
136
154
|
dump_db
|
137
155
|
stop_service(:postgresql)
|
156
|
+
stopped = true
|
138
157
|
else
|
139
158
|
dump_db
|
140
159
|
end
|
141
160
|
end
|
142
161
|
write_manifest
|
143
162
|
create_tarball
|
144
|
-
start_chef_server if
|
163
|
+
start_chef_server if stopped
|
145
164
|
export_tarball
|
146
165
|
cleanup
|
147
166
|
log 'Backup Complete!'
|
@@ -156,7 +175,7 @@ class TarBackup
|
|
156
175
|
def create_tarball
|
157
176
|
log 'Creating backup tarball'
|
158
177
|
cmd = [
|
159
|
-
"tar -czf #{tmp_dir}
|
178
|
+
"tar -czf #{tmp_dir}/#{export_filename}",
|
160
179
|
data_map.services.map { |_, v| v['data_dir'] }.compact.join(' '),
|
161
180
|
data_map.configs.map { |_, v| v['data_dir'] }.compact.join(' '),
|
162
181
|
Dir["#{tmp_dir}/*"].map { |f| File.basename(f) }.join(' ')
|
@@ -168,19 +187,40 @@ class TarBackup
|
|
168
187
|
|
169
188
|
def export_tarball
|
170
189
|
log "Exporting tarball to #{export_dir}"
|
171
|
-
cmd = "rsync -chaz #{tmp_dir}
|
190
|
+
cmd = "rsync -chaz #{tmp_dir}/#{export_filename} #{export_dir}/"
|
172
191
|
|
173
192
|
res = shell_out(cmd)
|
174
193
|
res
|
175
194
|
end
|
176
195
|
|
196
|
+
def export_filename
|
197
|
+
postfix = if config_only?
|
198
|
+
'-config'
|
199
|
+
else
|
200
|
+
''
|
201
|
+
end
|
202
|
+
"chef-backup#{postfix}-#{backup_time}.tgz"
|
203
|
+
end
|
204
|
+
|
205
|
+
def service_enabled?(service)
|
206
|
+
service_config[service] && service_config[service]['enable'] && !service_config[service]['external']
|
207
|
+
end
|
208
|
+
|
209
|
+
def external_pg?
|
210
|
+
service_config['postgresql']['external']
|
211
|
+
end
|
212
|
+
|
177
213
|
def pg_dump?
|
178
214
|
# defaults to true
|
179
|
-
|
215
|
+
service_config['backup']['always_dump_db']
|
180
216
|
end
|
181
217
|
|
182
218
|
def offline_permission_granted?
|
183
|
-
|
219
|
+
service_config['backup']['agree_to_go_offline']
|
220
|
+
end
|
221
|
+
|
222
|
+
def config_only?
|
223
|
+
service_config['backup']['config_only']
|
184
224
|
end
|
185
225
|
|
186
226
|
def ask_to_go_offline
|
@@ -15,18 +15,19 @@ class TarRestore
|
|
15
15
|
extend Forwardable
|
16
16
|
|
17
17
|
attr_accessor :tarball_path
|
18
|
+
attr_writer :manifest
|
18
19
|
|
19
20
|
def_delegators :@log, :log
|
20
21
|
|
21
22
|
def initialize(path)
|
22
23
|
@tarball_path = path
|
23
|
-
@log = ChefBackup::Logger.logger(
|
24
|
+
@log = ChefBackup::Logger.logger(service_config['backup']['logfile'] || nil)
|
24
25
|
end
|
25
26
|
|
26
27
|
def restore
|
27
28
|
log 'Restoring Chef Server from backup'
|
28
29
|
cleanse_chef_server(config['agree_to_cleanse'])
|
29
|
-
if
|
30
|
+
if ha?
|
30
31
|
log 'Performing HA restore - please ensure that keepalived is not running on the standby host'
|
31
32
|
fix_ha_plugins
|
32
33
|
check_ha_volume
|
@@ -35,10 +36,13 @@ class TarRestore
|
|
35
36
|
restore_configs
|
36
37
|
restore_services unless frontend?
|
37
38
|
touch_sentinel
|
39
|
+
reconfigure_marketplace if marketplace?
|
38
40
|
reconfigure_server
|
39
41
|
update_config
|
40
42
|
import_db if restore_db_dump?
|
41
43
|
start_chef_server
|
44
|
+
reconfigure_add_ons
|
45
|
+
restart_add_ons
|
42
46
|
cleanup
|
43
47
|
log 'Restoration Completed!'
|
44
48
|
end
|
@@ -64,15 +68,15 @@ class TarRestore
|
|
64
68
|
"chef_backup-#{manifest['backup_time']}.sql")
|
65
69
|
ensure_file!(sql_file, InvalidDatabaseDump, "#{sql_file} not found")
|
66
70
|
|
67
|
-
cmd = [
|
71
|
+
cmd = [chpst,
|
68
72
|
"-u #{manifest['services']['postgresql']['username']}",
|
69
|
-
|
73
|
+
pgsql,
|
70
74
|
"-U #{manifest['services']['postgresql']['username']}",
|
71
|
-
|
75
|
+
"-d #{database_name}",
|
72
76
|
"< #{sql_file}"
|
73
77
|
].join(' ')
|
74
78
|
log 'Importing Database dump'
|
75
|
-
shell_out!(cmd)
|
79
|
+
shell_out!(cmd, env: ["PGOPTIONS=#{pg_options}"])
|
76
80
|
end
|
77
81
|
|
78
82
|
def restore_services
|
@@ -123,7 +127,7 @@ class TarRestore
|
|
123
127
|
ha_data_dir = manifest['ha']['path']
|
124
128
|
|
125
129
|
unless ha_data_dir_mounted?(ha_data_dir)
|
126
|
-
|
130
|
+
raise "Please mount the data directory #{ha_data_dir} and perform any DRBD configuration before continuing"
|
127
131
|
end
|
128
132
|
end
|
129
133
|
|
@@ -139,17 +143,17 @@ class TarRestore
|
|
139
143
|
|
140
144
|
def reconfigure_server
|
141
145
|
log 'Reconfiguring the Chef Server'
|
142
|
-
shell_out(
|
146
|
+
shell_out("#{ctl_command} reconfigure")
|
143
147
|
end
|
144
148
|
|
145
149
|
def cleanse_chef_server(agree)
|
146
150
|
log 'Cleaning up any old files'
|
147
|
-
shell_out!("
|
151
|
+
shell_out!("#{ctl_command} cleanse #{agree || ''}")
|
148
152
|
end
|
149
153
|
|
150
154
|
def running_config
|
151
155
|
@running_config ||=
|
152
|
-
JSON.parse(File.read(
|
156
|
+
JSON.parse(File.read(running_filepath)) || {}
|
153
157
|
end
|
154
158
|
|
155
159
|
def update_config
|
data/lib/chef_backup/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -17,11 +17,6 @@ def private_chef!(args = {})
|
|
17
17
|
ChefBackup::Config.config = args
|
18
18
|
end
|
19
19
|
|
20
|
-
# Merge attributes into existing cli_args
|
21
|
-
def cli_args(*args)
|
22
|
-
Chef::Mixin::DeepMerge.deep_merge!(*args, ChefBackup::Config.config)
|
23
|
-
end
|
24
|
-
|
25
20
|
# Overwrite config with given CLI args
|
26
21
|
def cli_args!(args)
|
27
22
|
ChefBackup::Config.config = args
|
@@ -26,6 +26,15 @@ describe ChefBackup::Strategy::TarBackup do
|
|
26
26
|
allow(subject).to receive(:dump_db).and_return(true)
|
27
27
|
end
|
28
28
|
|
29
|
+
context 'when config_only is true' do
|
30
|
+
before do
|
31
|
+
private_chef('backup' => { 'config_only' => true })
|
32
|
+
end
|
33
|
+
|
34
|
+
it_behaves_like 'a tar based backup'
|
35
|
+
it_behaves_like 'a tar based frontend'
|
36
|
+
end
|
37
|
+
|
29
38
|
context 'on a frontend' do
|
30
39
|
before { private_chef('role' => 'frontend') }
|
31
40
|
|
@@ -98,13 +107,14 @@ describe ChefBackup::Strategy::TarBackup do
|
|
98
107
|
].join(' ')
|
99
108
|
end
|
100
109
|
|
110
|
+
let(:pg_options) { ["PGOPTIONS=#{ChefBackup::Helpers::DEFAULT_PG_OPTIONS}"] }
|
101
111
|
let(:tmp_dir) { '/tmp/notaswear' }
|
102
112
|
let(:backup_time) { Time.now }
|
103
113
|
|
104
114
|
before do
|
105
115
|
allow(subject).to receive(:tmp_dir).and_return(tmp_dir)
|
106
116
|
allow(subject).to receive(:backup_time).and_return(backup_time)
|
107
|
-
allow(subject).to receive(:shell_out!).with(dump_cmd).and_return(true)
|
117
|
+
allow(subject).to receive(:shell_out!).with(dump_cmd, env: pg_options).and_return(true)
|
108
118
|
private_chef('postgresql' => { 'username' => 'opscode-pgsql' })
|
109
119
|
subject.data_map.add_service('postgresql', '/data/dir')
|
110
120
|
end
|
@@ -116,7 +126,7 @@ describe ChefBackup::Strategy::TarBackup do
|
|
116
126
|
end
|
117
127
|
|
118
128
|
it 'dumps the db' do
|
119
|
-
expect(subject).to receive(:shell_out!).with(dump_cmd)
|
129
|
+
expect(subject).to receive(:shell_out!).with(dump_cmd, env: pg_options)
|
120
130
|
subject.dump_db
|
121
131
|
end
|
122
132
|
|
@@ -181,12 +191,13 @@ describe ChefBackup::Strategy::TarBackup do
|
|
181
191
|
|
182
192
|
describe '.write_manifest' do
|
183
193
|
let(:manifest) do
|
184
|
-
{ 'some' =>
|
185
|
-
|
186
|
-
'
|
187
|
-
|
188
|
-
|
189
|
-
|
194
|
+
{ 'some' =>
|
195
|
+
{
|
196
|
+
'nested' => {
|
197
|
+
'hash' => true
|
198
|
+
},
|
199
|
+
'another' => true
|
200
|
+
}
|
190
201
|
}
|
191
202
|
end
|
192
203
|
|
@@ -269,6 +280,28 @@ describe ChefBackup::Strategy::TarBackup do
|
|
269
280
|
end
|
270
281
|
end
|
271
282
|
|
283
|
+
context 'when config_only is true' do
|
284
|
+
before do
|
285
|
+
private_chef('role' => 'standalone', 'backup' => { 'config_only' => true })
|
286
|
+
data_mock = double('DataMap')
|
287
|
+
allow(subject).to receive(:data_map).and_return(data_mock)
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'populates the data map with config and upgrade directories only' do
|
291
|
+
configs.each do |config|
|
292
|
+
expect(subject.data_map)
|
293
|
+
.to receive(:add_config)
|
294
|
+
.with(config, "/etc/#{config}")
|
295
|
+
end
|
296
|
+
|
297
|
+
expect(subject.data_map)
|
298
|
+
.to receive(:add_service)
|
299
|
+
.with('upgrades', '/var/opt/opscode/upgrades')
|
300
|
+
|
301
|
+
subject.populate_data_map
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
272
305
|
context 'on a frontend' do
|
273
306
|
before { private_chef(config.merge('role' => 'frontend')) }
|
274
307
|
|
@@ -41,7 +41,7 @@ describe ChefBackup::Strategy::TarRestore do
|
|
41
41
|
before do
|
42
42
|
%i(shell_out shell_out! unpack_tarball stop_chef_server ensure_file!
|
43
43
|
start_chef_server reconfigure_server cleanse_chef_server
|
44
|
-
update_config import_db touch_sentinel
|
44
|
+
update_config import_db touch_sentinel restart_add_ons
|
45
45
|
).each do |method|
|
46
46
|
allow(subject).to receive(method).and_return(true)
|
47
47
|
end
|
@@ -60,6 +60,7 @@ describe ChefBackup::Strategy::TarRestore do
|
|
60
60
|
|
61
61
|
allow(subject).to receive(:tarball_path).and_return(tarball_path)
|
62
62
|
allow(subject).to receive(:manifest).and_return(manifest)
|
63
|
+
allow(subject).to receive(:marketplace?).and_return(false)
|
63
64
|
end
|
64
65
|
|
65
66
|
it_behaves_like 'a tar based restore'
|
@@ -121,11 +122,25 @@ describe ChefBackup::Strategy::TarRestore do
|
|
121
122
|
|
122
123
|
it_behaves_like 'a tar based backend restore without db dump'
|
123
124
|
end
|
125
|
+
|
126
|
+
context 'on a marketplace all-in-one' do
|
127
|
+
before do
|
128
|
+
allow(subject).to receive(:marketplace?).and_return(true)
|
129
|
+
allow(subject).to receive(:reconfigure_marketplace?).and_return(true)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'sets up chef-marketplace' do
|
133
|
+
expect(subject).to receive(:reconfigure_marketplace).once
|
134
|
+
subject.restore
|
135
|
+
end
|
136
|
+
|
137
|
+
it_behaves_like 'a tar based backend restore'
|
138
|
+
end
|
124
139
|
end
|
125
140
|
end
|
126
141
|
|
127
142
|
describe '.manifest' do
|
128
|
-
let(:json) {
|
143
|
+
let(:json) { '{"some":"json"}' }
|
129
144
|
let(:manifest_json) { File.join(restore_dir, 'manifest.json') }
|
130
145
|
|
131
146
|
it 'parses the manifest from the restore dir' do
|
@@ -177,6 +192,8 @@ describe ChefBackup::Strategy::TarRestore do
|
|
177
192
|
end
|
178
193
|
|
179
194
|
describe '.import_db' do
|
195
|
+
let(:pg_options) { ["PGOPTIONS=#{ChefBackup::Helpers::DEFAULT_PG_OPTIONS}"] }
|
196
|
+
|
180
197
|
before do
|
181
198
|
allow(subject).to receive(:manifest).and_return(manifest)
|
182
199
|
allow(subject).to receive(:shell_out!).and_return(true)
|
@@ -214,7 +231,7 @@ describe ChefBackup::Strategy::TarRestore do
|
|
214
231
|
end
|
215
232
|
|
216
233
|
it 'imports the database' do
|
217
|
-
expect(subject).to receive(:shell_out!).with(import_cmd)
|
234
|
+
expect(subject).to receive(:shell_out!).with(import_cmd, env: pg_options)
|
218
235
|
subject.import_db
|
219
236
|
end
|
220
237
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef_backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Cragun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: di-ruby-lvm
|
@@ -140,16 +140,16 @@ dependencies:
|
|
140
140
|
name: rubocop
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
145
|
+
version: 0.37.2
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
152
|
+
version: 0.37.2
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: simplecov
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,12 +228,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
228
228
|
version: '0'
|
229
229
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
230
|
requirements:
|
231
|
-
- - "
|
231
|
+
- - ">="
|
232
232
|
- !ruby/object:Gem::Version
|
233
|
-
version:
|
233
|
+
version: '0'
|
234
234
|
requirements: []
|
235
235
|
rubyforge_project:
|
236
|
-
rubygems_version: 2.
|
236
|
+
rubygems_version: 2.5.1
|
237
237
|
signing_key:
|
238
238
|
specification_version: 4
|
239
239
|
summary: A library to backup a Chef Server
|
@@ -251,4 +251,3 @@ test_files:
|
|
251
251
|
- spec/unit/strategy/restore/shared_examples/restore.rb
|
252
252
|
- spec/unit/strategy/restore/tar_spec.rb
|
253
253
|
- spec/unit/strategy_spec.rb
|
254
|
-
has_rdoc:
|