chef_backup 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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