chef_backup 0.0.1.dev.4 → 0.2.0.pre1

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 (40) hide show
  1. checksums.yaml +5 -5
  2. data/lib/chef_backup/config.rb +22 -12
  3. data/lib/chef_backup/data_map.rb +18 -12
  4. data/lib/chef_backup/deep_merge.rb +145 -0
  5. data/lib/chef_backup/helpers.rb +154 -28
  6. data/lib/chef_backup/logger.rb +11 -6
  7. data/lib/chef_backup/mash.rb +226 -0
  8. data/lib/chef_backup/runner.rb +24 -21
  9. data/lib/chef_backup/strategy/backup/custom.rb +1 -2
  10. data/lib/chef_backup/strategy/backup/ebs.rb +3 -6
  11. data/lib/chef_backup/strategy/backup/lvm.rb +2 -4
  12. data/lib/chef_backup/strategy/backup/object.rb +2 -4
  13. data/lib/chef_backup/strategy/backup/tar.rb +96 -40
  14. data/lib/chef_backup/strategy/restore/tar.rb +81 -51
  15. data/lib/chef_backup/strategy.rb +10 -10
  16. data/lib/chef_backup/version.rb +1 -1
  17. data/lib/chef_backup.rb +8 -8
  18. metadata +21 -162
  19. data/.gitignore +0 -23
  20. data/.kitchen.yml +0 -30
  21. data/.rubocop.yml +0 -21
  22. data/.travis.yml +0 -6
  23. data/Gemfile +0 -4
  24. data/Guardfile +0 -22
  25. data/README.md +0 -21
  26. data/Rakefile +0 -44
  27. data/chef_backup.gemspec +0 -33
  28. data/spec/fixtures/chef-server-running.json +0 -589
  29. data/spec/spec_helper.rb +0 -103
  30. data/spec/unit/data_map_spec.rb +0 -59
  31. data/spec/unit/helpers_spec.rb +0 -88
  32. data/spec/unit/runner_spec.rb +0 -185
  33. data/spec/unit/shared_examples/helpers.rb +0 -20
  34. data/spec/unit/strategy/backup/lvm_spec.rb +0 -0
  35. data/spec/unit/strategy/backup/shared_examples/backup.rb +0 -92
  36. data/spec/unit/strategy/backup/tar_spec.rb +0 -294
  37. data/spec/unit/strategy/restore/lvm_spec.rb +0 -0
  38. data/spec/unit/strategy/restore/shared_examples/restore.rb +0 -84
  39. data/spec/unit/strategy/restore/tar_spec.rb +0 -238
  40. data/spec/unit/strategy_spec.rb +0 -36
data/spec/spec_helper.rb DELETED
@@ -1,103 +0,0 @@
1
- require 'simplecov'
2
- SimpleCov.start
3
-
4
- require 'chef_backup'
5
- require 'bundler/setup'
6
- require 'json'
7
- require 'tempfile'
8
- require 'chef/mixin/deep_merge'
9
-
10
- # Merge attributes into existing running_config
11
- def private_chef(*args)
12
- Chef::Mixin::DeepMerge.deep_merge!(*args, ChefBackup::Config['private_chef'])
13
- end
14
-
15
- # Overwrite config with given attributes
16
- def private_chef!(args = {})
17
- ChefBackup::Config.config = args
18
- end
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
- # Overwrite config with given CLI args
26
- def cli_args!(args)
27
- ChefBackup::Config.config = args
28
- end
29
-
30
- def use_default_running_config
31
- ChefBackup::Config.config = running_config
32
- end
33
-
34
- def use_default_cli_args
35
- ChefBackup::Config.config = cli_args
36
- end
37
-
38
- def clear_config
39
- ChefBackup::Config.config = {}
40
- end
41
-
42
- def set_common_variables
43
- let(:backup_tarball) { '/tmp/chef-backup-2014-12-10-20-31-40.tgz' }
44
- let(:backup_time) { '2014-08-21T23:10:57-07:00' }
45
- let(:tmp_dir) { '/tmp/chef-backup' }
46
- let(:strategy) { 'test' }
47
- let(:export_dir) { '/mnt/chef-backups' }
48
- let(:all_services) do
49
- %w(nginx oc_bifrost oc_id opscode-erchef opscode-expander
50
- opscode-expander-reindexer opscode-solr4 postgresql rabbitmq redis_lb
51
- )
52
- end
53
- let(:enabled_services) { all_services }
54
- let(:data_map) do
55
- double(
56
- 'DataMap',
57
- services: {
58
- 'postgresql' => {
59
- 'data_dir' => '/var/opt/opscode/postgresql_9.2/data'
60
- },
61
- 'couchdb' => {
62
- 'data_dir' => '/var/opt/opscode/couchdb/data'
63
- },
64
- 'rabbitmq' => {
65
- 'data_dir' => '/var/opt/opscode/rabbitdb/data'
66
- }
67
- },
68
- configs: {
69
- 'opscode' => {
70
- 'data_dir' => '/etc/opscode'
71
- },
72
- 'opscode-manage' => {
73
- 'data_dir' => '/etc/opscode-manage'
74
- }
75
- }
76
- )
77
- end
78
- end
79
-
80
- def running_config
81
- @config ||= begin
82
- f = File.expand_path('../fixtures/chef-server-running.json', __FILE__)
83
- JSON.parse(File.read(f))
84
- end
85
- @config.dup
86
- end
87
-
88
- def cli_args
89
- {
90
- 'tmp_dir' => '/tmp/chef_backup/tmp_dir',
91
- 'agree_to_cleanse' => nil,
92
- 'restore_arg' => '/tmp/chef_backup/backup.tgz',
93
- 'restore_dir' => File.join('/tmp/chef_backup/tmp_dir', 'restore_dir')
94
- }
95
- end
96
-
97
- RSpec.configure do |rspec|
98
- rspec.run_all_when_everything_filtered = true
99
- rspec.filter_run :focus
100
- rspec.order = 'random'
101
- rspec.expect_with(:rspec) { |c| c.syntax = :expect }
102
- rspec.before { allow($stdout).to receive(:write) }
103
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ChefBackup::DataMap do
4
- set_common_variables
5
-
6
- describe '.initialize' do
7
- it 'yields a config block' do
8
- expect { |b| described_class.new(&b) }.to yield_with_args
9
- end
10
- end
11
-
12
- describe '.add_service' do
13
- subject { described_class.new }
14
-
15
- it 'adds a service' do
16
- subject.add_service('bookshelf', '/bookshelf/path')
17
- expect(subject.services.keys.count).to eq(1)
18
- expect(subject.services['bookshelf']['data_dir']).to eq('/bookshelf/path')
19
- end
20
- end
21
-
22
- describe '.add_config' do
23
- subject { described_class.new }
24
-
25
- it 'adds a config' do
26
- subject.add_config('opscode-manage', '/opscode-manage/path')
27
- expect(subject.configs.keys.count).to eq(1)
28
- expect(subject.configs['opscode-manage']['data_dir'])
29
- .to eq('/opscode-manage/path')
30
- end
31
- end
32
-
33
- describe '.manifest' do
34
- subject do
35
- described_class.new do |dm|
36
- dm.strategy = 'test'
37
- dm.backup_time = backup_time
38
- dm.add_config('somethingstrange', 'inthehood')
39
- dm.add_service('whoyagonnacall', 'ghostbusters')
40
- end
41
- end
42
-
43
- it 'includes the backup strategy type' do
44
- expect(subject.manifest).to include('strategy' => 'test')
45
- end
46
-
47
- it 'includes the backup timestamp' do
48
- expect(subject.manifest).to include('backup_time' => backup_time)
49
- end
50
-
51
- it 'includes the backup config' do
52
- expect(subject.manifest).to include('configs' => subject.configs)
53
- end
54
-
55
- it 'includes the backup service' do
56
- expect(subject.manifest).to include('services' => subject.services)
57
- end
58
- end
59
- end
@@ -1,88 +0,0 @@
1
- require 'spec_helper'
2
- require_relative 'shared_examples/helpers'
3
-
4
- describe ChefBackup::Helpers do
5
- let(:tmp_dir_path) { '/tmp/chef_backup/tmp_dir' }
6
-
7
- before do
8
- # Test class to include our helpers methods
9
- class HelperTest; include ChefBackup::Helpers; end
10
- end
11
-
12
- after do
13
- Object.send(:remove_const, :HelperTest)
14
- end
15
-
16
- subject { HelperTest.new }
17
-
18
- describe '.tmp_dir' do
19
- context 'with CLI args' do
20
- before { private_chef!('tmp_dir' => tmp_dir_path) }
21
-
22
- context 'when the directory exists' do
23
- before do
24
- allow(File)
25
- .to receive(:directory?).with(tmp_dir_path).and_return(true)
26
- end
27
-
28
- it_behaves_like '.tmp_dir with an existing specified directory'
29
- end
30
-
31
- context 'when the directory does not exist' do
32
- before do
33
- allow(File)
34
- .to receive(:directory?).with(tmp_dir_path).and_return(false)
35
- allow(FileUtils)
36
- .to receive(:mkdir_p).with(tmp_dir_path).and_return([tmp_dir_path])
37
- end
38
-
39
- it_behaves_like '.tmp_dir with a nonexisting specified directory'
40
- end
41
- end
42
-
43
- context 'with running_config args' do
44
- before { private_chef!('tmp_dir' => tmp_dir_path) }
45
-
46
- context 'when the directory exists' do
47
- before do
48
- allow(File)
49
- .to receive(:directory?).with(tmp_dir_path).and_return(true)
50
- end
51
-
52
- it_behaves_like '.tmp_dir with an existing specified directory'
53
- end
54
-
55
- context 'when the directory does not exist' do
56
- before do
57
- allow(File)
58
- .to receive(:directory?).with(tmp_dir_path).and_return(false)
59
- allow(FileUtils)
60
- .to receive(:mkdir_p).with(tmp_dir_path).and_return([tmp_dir_path])
61
- end
62
-
63
- it_behaves_like '.tmp_dir with a nonexisting specified directory'
64
- end
65
- end
66
-
67
- context 'when no args are passed' do
68
- before do
69
- clear_config
70
- allow(Dir).to receive(:mktmpdir).with('chef_backup')
71
- end
72
-
73
- it_behaves_like '.tmp_dir without a specified directory'
74
- end
75
- end
76
-
77
- describe '.cleanup' do
78
- before do
79
- allow(subject).to receive(:tmp_dir).and_return(tmp_dir_path)
80
- allow(FileUtils).to receive(:rm_r).with(tmp_dir_path)
81
- end
82
-
83
- it 'cleans up all items in the temp directory' do
84
- expect(FileUtils).to receive(:rm_r).with(tmp_dir_path)
85
- subject.cleanup
86
- end
87
- end
88
- end
@@ -1,185 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ChefBackup::Runner do
4
- let(:test_strategy) { double('TestBackup', backup: true, restore: true) }
5
- let(:backup_tarball) { '/tmp/chef-backup-2014-12-10-20-31-40.tgz' }
6
- let(:backup_name) { 'chef-backup-2014-12-10-20-31-40' }
7
- let(:restore_dir) { ChefBackup::Config['restore_dir'] }
8
- let(:manifest_json) { "#{restore_dir}/manifest.json" }
9
- let(:manifest) { { 'strategy' => 'test_strategy' } }
10
- let(:json) { '{"some":{"nested":{"hash":1}}}' }
11
- let(:runner_config) do
12
- {
13
- 'tmp_dir' => '/tmp/runner_spec_tmp_dir',
14
- 'restore_param' => backup_tarball,
15
- 'agree_to_cleanse' => 'yes',
16
- 'private_chef' => { 'backup' => { 'strategy' => 'test' } }
17
- }
18
- end
19
-
20
- subject { described_class.new(runner_config) }
21
-
22
- describe '.backup' do
23
- it 'initializes a ChefBackup::Strategy and calls .backup' do
24
- allow(ChefBackup::Strategy)
25
- .to receive(:backup)
26
- .with('test')
27
- .and_return(test_strategy)
28
-
29
- expect(test_strategy).to receive(:backup).once
30
- subject.backup
31
- end
32
- end
33
-
34
- describe '.restore' do
35
- it 'initializes a ChefBackup::Strategy and calls .restore' do
36
- allow(subject).to receive(:restore_strategy).and_return('test')
37
- allow(ChefBackup::Strategy)
38
- .to receive(:restore)
39
- .with('test', backup_tarball)
40
- .and_return(test_strategy)
41
-
42
- expect(test_strategy).to receive(:restore).once
43
- subject.restore
44
- end
45
- end
46
-
47
- describe '.manifest' do
48
- before do
49
- allow(subject).to receive(:restore_directory).and_return(restore_dir)
50
- allow(subject).to receive(:ensure_file!).and_return(true)
51
- allow(File).to receive(:read).with(manifest_json).and_return(json)
52
- end
53
-
54
- it 'verifies that the file exists' do
55
- expect(subject).to receive(:ensure_file!)
56
- subject.manifest
57
- end
58
-
59
- it 'parses the manifest.json' do
60
- expect(subject.manifest).to eq(JSON.parse(json).to_h)
61
- end
62
- end
63
-
64
- describe '.restore_directory' do
65
- let(:rest_dir) do
66
- ChefBackup::Config['tmp_dir'] = '/tmp/chef_backup'
67
- File.join(ChefBackup::Config['tmp_dir'], backup_name)
68
- end
69
-
70
- before(:each) do
71
- ChefBackup::Config['tmp_dir'] = '/tmp/chef_backup'
72
- allow(subject).to receive(:backup_name).and_return(backup_name)
73
- end
74
-
75
- context 'when the restore directory already exists' do
76
- before do
77
- allow(File).to receive(:directory?).and_return(true)
78
- allow(Dir).to receive(:glob).and_return(%w(a b c))
79
- allow(FileUtils).to receive(:rm_r).and_return(true)
80
- end
81
-
82
- it 'cleans the restore directory' do
83
- # The directory needs to exist but has not been set in the config
84
- ChefBackup::Config['restore_dir'] = nil
85
- expect(FileUtils).to receive(:rm_r).with(%w(a b c))
86
- subject.restore_directory
87
- end
88
-
89
- it 'does not create a new directory' do
90
- ChefBackup::Config['restore_dir'] = '/tmp/restore_dir'
91
- subject.restore_directory
92
- expect(ChefBackup::Config['restore_dir']).to eq(restore_dir)
93
- end
94
- end
95
-
96
- context 'when the restore directory does not exist' do
97
- before do
98
- allow(File).to receive(:directory?).and_return(false)
99
- allow(FileUtils).to receive(:rm_r).and_return(true)
100
- allow(FileUtils).to receive(:mkdir_p).and_return(true)
101
- end
102
-
103
- it 'creates a restore directory in the runner tmp_dir' do
104
- ChefBackup::Config['restore_dir'] = nil
105
- expect(FileUtils).to receive(:mkdir_p).with(rest_dir)
106
- subject.restore_directory
107
- end
108
-
109
- it 'updates the config with the restore dir' do
110
- ChefBackup::Config['restore_dir'] = nil
111
- subject.restore_directory
112
- expect(ChefBackup::Config['restore_dir']).to eq(restore_dir)
113
- end
114
- end
115
- end
116
-
117
- describe '.unpack_tarball' do
118
- before do
119
- allow(subject).to receive(:restore_param).and_return(backup_tarball)
120
- allow(subject).to receive(:restore_directory).and_return(restore_dir)
121
- allow(subject).to receive(:shell_out!).and_return(true)
122
- end
123
-
124
- it 'raises an error if the tarball is invalid' do
125
- allow(File)
126
- .to receive(:exist?).with(backup_tarball).and_return(false)
127
- expect { subject.unpack_tarball }
128
- .to raise_error(ChefBackup::Exceptions::InvalidTarball,
129
- "#{backup_tarball} not found")
130
- end
131
-
132
- it 'explodes the tarball into the restore directory' do
133
- allow(subject).to receive(:ensure_file!).and_return(true)
134
-
135
- cmd = "tar zxf #{backup_tarball} -C #{restore_dir}"
136
- expect(subject).to receive(:shell_out!).with(cmd)
137
- subject.unpack_tarball
138
- end
139
- end
140
-
141
- describe '.restore_strategy' do
142
- context 'when the restore param is a tarball' do
143
- before do
144
- allow(subject).to receive(:tarball?).and_return(true)
145
- allow(subject).to receive(:unpack_tarball).and_return(true)
146
- allow(subject).to receive(:manifest).and_return(manifest)
147
- end
148
-
149
- it 'unpacks the tarball' do
150
- expect(subject).to receive(:unpack_tarball)
151
- subject.restore_strategy
152
- end
153
-
154
- it 'returns the strategy from the manifest' do
155
- expect(subject.restore_strategy).to eq('test_strategy')
156
- subject.restore_strategy
157
- end
158
- end
159
-
160
- context 'when the restore param is an ebs snapshot' do
161
- before do
162
- allow(subject).to receive(:tarball?).and_return(false)
163
- allow(subject).to receive(:ebs_snapshot?).and_return(true)
164
- end
165
-
166
- it 'returns "ebs" as the strategy' do
167
- expect(subject.restore_strategy).to eq('ebs')
168
- end
169
- end
170
-
171
- context 'when the restore param is not valid' do
172
- before do
173
- allow(subject).to receive(:tarball?).and_return(false)
174
- allow(subject).to receive(:ebs_snapshot?).and_return(false)
175
- allow(subject).to receive(:restore_param).and_return('invalid_param')
176
- end
177
-
178
- it 'raises an exception' do
179
- expect { subject.restore_strategy }
180
- .to raise_error(ChefBackup::Exceptions::InvalidStrategy,
181
- 'invalid_param is not a valid backup')
182
- end
183
- end
184
- end
185
- end
@@ -1,20 +0,0 @@
1
- shared_examples '.tmp_dir with a nonexisting specified directory' do
2
- it 'uses the specified directory' do
3
- expect(FileUtils).to receive(:mkdir_p).with(tmp_dir_path)
4
- expect(subject.tmp_dir).to eq(tmp_dir_path)
5
- end
6
- end
7
-
8
- shared_examples '.tmp_dir with an existing specified directory' do
9
- it 'does not create a directory' do
10
- expect(FileUtils).to_not receive(:anything)
11
- expect(subject.tmp_dir).to eq(tmp_dir_path)
12
- end
13
- end
14
-
15
- shared_examples '.tmp_dir without a specified directory' do
16
- it 'creates a temp directory' do
17
- expect(Dir).to receive(:mktmpdir).with('chef_backup')
18
- subject.tmp_dir
19
- end
20
- end
File without changes
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples 'a tar based backup' do
4
- it 'populates the data map with services and configs' do
5
- expect(subject).to receive(:populate_data_map).once
6
- subject.backup
7
- end
8
-
9
- it 'creates a backup manifest' do
10
- expect(subject).to receive(:write_manifest).once
11
- subject.backup
12
- end
13
-
14
- it 'creates a tarball of the backup' do
15
- expect(subject).to receive(:create_tarball).once
16
- subject.backup
17
- end
18
-
19
- it 'cleans up the temp directory' do
20
- expect(subject).to receive(:cleanup).at_least(:once)
21
- subject.backup
22
- end
23
- end
24
-
25
- shared_examples 'a tar based frontend' do
26
- it 'doesnt stop any services' do
27
- expect(subject).to_not receive(:stop_service)
28
- subject.backup
29
- end
30
-
31
- it 'doesnt dump the db' do
32
- expect(subject).to_not receive(:dump_db)
33
- subject.backup
34
- end
35
- end
36
-
37
- shared_examples 'a tar based online backend' do
38
- it "doesn't start any services" do
39
- expect(subject).to_not receive(:start_service)
40
- subject.backup
41
- end
42
-
43
- it "doesn't stop any services" do
44
- expect(subject).to_not receive(:stop_service)
45
- subject.backup
46
- end
47
-
48
- it 'dumps the db' do
49
- expect(subject).to receive(:dump_db).once
50
- subject.backup
51
- end
52
- end
53
-
54
- shared_examples 'a tar based offline backend' do
55
- it 'stops all services besides keepalived and postgres' do
56
- expect(subject).to receive(:stop_chef_server).once
57
-
58
- %w(postgresql keepalived).each do |service|
59
- expect(subject).to_not receive(:stop_service).with(service)
60
- end
61
-
62
- subject.backup
63
- end
64
-
65
- it 'starts all the services again' do
66
- expect(subject).to receive(:start_chef_server).at_least(:once)
67
- subject.backup
68
- end
69
-
70
- it 'dumps the db' do
71
- expect(subject).to receive(:dump_db).once
72
- subject.backup
73
- end
74
-
75
- context 'when the user has not agreed to go offline' do
76
- before { private_chef('backup' => { 'agree_to_go_offline' => false }) }
77
-
78
- it 'prompts the user' do
79
- expect(subject).to receive(:ask_to_go_offline).once
80
- subject.backup
81
- end
82
- end
83
-
84
- context 'when the user has agreed to go offline' do
85
- before { private_chef('backup' => { 'agree_to_go_offline' => true }) }
86
-
87
- it 'prompts the user' do
88
- expect(subject).to_not receive(:ask_to_go_offline)
89
- subject.backup
90
- end
91
- end
92
- end