chef_backup 0.0.1 → 0.1.0

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.rb +8 -8
  3. data/lib/chef_backup/config.rb +17 -17
  4. data/lib/chef_backup/data_map.rb +18 -12
  5. data/lib/chef_backup/deep_merge.rb +145 -0
  6. data/lib/chef_backup/helpers.rb +46 -10
  7. data/lib/chef_backup/logger.rb +2 -2
  8. data/lib/chef_backup/mash.rb +226 -0
  9. data/lib/chef_backup/runner.rb +11 -13
  10. data/lib/chef_backup/strategy.rb +10 -10
  11. data/lib/chef_backup/strategy/backup/custom.rb +1 -2
  12. data/lib/chef_backup/strategy/backup/ebs.rb +3 -6
  13. data/lib/chef_backup/strategy/backup/lvm.rb +2 -4
  14. data/lib/chef_backup/strategy/backup/object.rb +2 -4
  15. data/lib/chef_backup/strategy/backup/tar.rb +23 -7
  16. data/lib/chef_backup/strategy/restore/tar.rb +69 -43
  17. data/lib/chef_backup/version.rb +1 -1
  18. metadata +20 -168
  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 -98
  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 -327
  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 -255
  40. data/spec/unit/strategy_spec.rb +0 -36
@@ -1,98 +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
- # Overwrite config with given CLI args
21
- def cli_args!(args)
22
- ChefBackup::Config.config = args
23
- end
24
-
25
- def use_default_running_config
26
- ChefBackup::Config.config = running_config
27
- end
28
-
29
- def use_default_cli_args
30
- ChefBackup::Config.config = cli_args
31
- end
32
-
33
- def clear_config
34
- ChefBackup::Config.config = {}
35
- end
36
-
37
- def set_common_variables
38
- let(:backup_tarball) { '/tmp/chef-backup-2014-12-10-20-31-40.tgz' }
39
- let(:backup_time) { '2014-08-21T23:10:57-07:00' }
40
- let(:tmp_dir) { '/tmp/chef-backup' }
41
- let(:strategy) { 'test' }
42
- let(:export_dir) { '/mnt/chef-backups' }
43
- let(:all_services) do
44
- %w(nginx oc_bifrost oc_id opscode-erchef opscode-expander
45
- opscode-expander-reindexer opscode-solr4 postgresql rabbitmq redis_lb
46
- )
47
- end
48
- let(:enabled_services) { all_services }
49
- let(:data_map) do
50
- double(
51
- 'DataMap',
52
- services: {
53
- 'postgresql' => {
54
- 'data_dir' => '/var/opt/opscode/postgresql_9.2/data'
55
- },
56
- 'couchdb' => {
57
- 'data_dir' => '/var/opt/opscode/couchdb/data'
58
- },
59
- 'rabbitmq' => {
60
- 'data_dir' => '/var/opt/opscode/rabbitdb/data'
61
- }
62
- },
63
- configs: {
64
- 'opscode' => {
65
- 'data_dir' => '/etc/opscode'
66
- },
67
- 'opscode-manage' => {
68
- 'data_dir' => '/etc/opscode-manage'
69
- }
70
- }
71
- )
72
- end
73
- end
74
-
75
- def running_config
76
- @config ||= begin
77
- f = File.expand_path('../fixtures/chef-server-running.json', __FILE__)
78
- JSON.parse(File.read(f))
79
- end
80
- @config.dup
81
- end
82
-
83
- def cli_args
84
- {
85
- 'tmp_dir' => '/tmp/chef_backup/tmp_dir',
86
- 'agree_to_cleanse' => nil,
87
- 'restore_arg' => '/tmp/chef_backup/backup.tgz',
88
- 'restore_dir' => File.join('/tmp/chef_backup/tmp_dir', 'restore_dir')
89
- }
90
- end
91
-
92
- RSpec.configure do |rspec|
93
- rspec.run_all_when_everything_filtered = true
94
- rspec.filter_run :focus
95
- rspec.order = 'random'
96
- rspec.expect_with(:rspec) { |c| c.syntax = :expect }
97
- rspec.before { allow($stdout).to receive(:write) }
98
- 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