backup_jenkins 0.0.1 → 0.0.2
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.
- data/Gemfile +9 -0
- data/Guardfile +8 -0
- data/config/{config-sample.yml → config-example.yml} +0 -0
- data/lib/backup_jenkins/aws.rb +17 -6
- data/lib/backup_jenkins/backup.rb +8 -14
- data/lib/backup_jenkins/config.rb +21 -1
- data/lib/backup_jenkins/version.rb +1 -1
- data/spec/lib/backup_jenkins/aws_spec.rb +146 -0
- data/spec/lib/backup_jenkins/backup_spec.rb +212 -0
- data/spec/lib/backup_jenkins/cli_spec.rb +31 -0
- data/spec/lib/backup_jenkins/config_spec.rb +42 -10
- data/spec/spec_helper.rb +3 -0
- metadata +39 -12
data/Gemfile
CHANGED
@@ -3,6 +3,15 @@ source :rubygems
|
|
3
3
|
# Specify your gem's dependencies in backup_jenkins.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
group :development do
|
7
|
+
gem "guard"
|
8
|
+
gem "guard-rspec"
|
9
|
+
gem "rb-inotify", require: false
|
10
|
+
gem "rb-fsevent", require: false
|
11
|
+
gem "rb-fchange", require: false
|
12
|
+
gem "terminal-notifier-guard"
|
13
|
+
end
|
14
|
+
|
6
15
|
group :test do
|
7
16
|
gem "rake"
|
8
17
|
gem "rspec"
|
data/Guardfile
ADDED
File without changes
|
data/lib/backup_jenkins/aws.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module BackupJenkins
|
2
2
|
class AWS
|
3
|
+
class UploadFileError < StandardError; end
|
4
|
+
|
3
5
|
def initialize(config = Config.new)
|
4
6
|
@config = config
|
5
7
|
setup_aws
|
@@ -7,22 +9,27 @@ module BackupJenkins
|
|
7
9
|
|
8
10
|
def populate_files
|
9
11
|
@files = []
|
10
|
-
|
12
|
+
backup_files.each{ |o| files << o }
|
11
13
|
@files.sort!{ |a, b| a.key <=> b.key }
|
12
14
|
end
|
13
15
|
|
16
|
+
def backup_files
|
17
|
+
s3_files.with_prefix(config.base_file_name)
|
18
|
+
end
|
19
|
+
|
14
20
|
# TODO change this to use a time decay algorithm
|
15
21
|
def remove_old_files
|
16
22
|
puts "Looking for old files..." if config.verbose
|
17
|
-
|
18
23
|
populate_files
|
24
|
+
do_remove_old_files
|
25
|
+
puts "Done." if config.verbose
|
26
|
+
end
|
19
27
|
|
28
|
+
def do_remove_old_files
|
20
29
|
files_to_remove.each do |file|
|
21
30
|
puts "Removing #{file.key}..." if config.verbose
|
22
31
|
file.delete
|
23
32
|
end
|
24
|
-
|
25
|
-
puts "Done." if config.verbose
|
26
33
|
end
|
27
34
|
|
28
35
|
def files_to_remove
|
@@ -31,9 +38,9 @@ module BackupJenkins
|
|
31
38
|
|
32
39
|
def upload_file(filename, file)
|
33
40
|
puts "About to upload #{filename}..." if config.verbose
|
34
|
-
new_file =
|
41
|
+
new_file = s3_files.create(filename, file)
|
35
42
|
puts "Done" if config.verbose
|
36
|
-
raise
|
43
|
+
raise UploadFileError unless new_file.class == ::AWS::S3::S3Object
|
37
44
|
end
|
38
45
|
|
39
46
|
private
|
@@ -50,5 +57,9 @@ module BackupJenkins
|
|
50
57
|
raise "Couldn't create bucket!" unless @bucket.exists?
|
51
58
|
end
|
52
59
|
|
60
|
+
def s3_files
|
61
|
+
bucket.objects
|
62
|
+
end
|
63
|
+
|
53
64
|
end
|
54
65
|
end
|
@@ -7,15 +7,7 @@ module BackupJenkins
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def backup_directory
|
10
|
-
@backup_directory ||= "#{config.backup["dir_base"]}/#{base_file_name}_#{timestamp}"
|
11
|
-
end
|
12
|
-
|
13
|
-
def base_file_name
|
14
|
-
"#{config.backup["file_name_base"]}_#{hostname}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def hostname
|
18
|
-
%x{hostname -s}.chomp
|
10
|
+
@backup_directory ||= "#{config.backup["dir_base"]}/#{config.base_file_name}_#{timestamp}"
|
19
11
|
end
|
20
12
|
|
21
13
|
def create_dir_and_copy(file_names)
|
@@ -28,12 +20,14 @@ module BackupJenkins
|
|
28
20
|
raise "file '#{file_name}' does not exist" unless FileTest.file?(file_name)
|
29
21
|
|
30
22
|
new_file_name = new_file_path(file_name)
|
31
|
-
|
23
|
+
new_file_dir = File.dirname(new_file_name)
|
24
|
+
|
25
|
+
FileUtils.mkdir_p(new_file_dir, verbose: config.verbose)
|
32
26
|
FileUtils.cp(file_name, new_file_name, verbose: config.verbose)
|
33
27
|
end
|
34
28
|
|
35
29
|
def new_file_path(file_name)
|
36
|
-
"#{backup_directory}/#{file_name.gsub(%r{#{config.jenkins["home"]}}, "")}"
|
30
|
+
"#{backup_directory}/#{file_name.gsub(%r{#{config.jenkins["home"]}}, "")}".gsub(%r{//}, '/')
|
37
31
|
end
|
38
32
|
|
39
33
|
def do_backup
|
@@ -80,9 +74,9 @@ module BackupJenkins
|
|
80
74
|
end
|
81
75
|
|
82
76
|
def tar_options
|
83
|
-
|
84
|
-
|
85
|
-
|
77
|
+
%w(j c f).tap do |options|
|
78
|
+
options.unshift('v') if config.verbose
|
79
|
+
end.join('')
|
86
80
|
end
|
87
81
|
|
88
82
|
private
|
@@ -3,7 +3,7 @@ module BackupJenkins
|
|
3
3
|
attr_reader :s3
|
4
4
|
|
5
5
|
def initialize
|
6
|
-
@config =
|
6
|
+
@config = config_file
|
7
7
|
end
|
8
8
|
|
9
9
|
def method_missing(meth, *args, &block)
|
@@ -15,9 +15,29 @@ module BackupJenkins
|
|
15
15
|
config.has_key?(meth.to_s) || super
|
16
16
|
end
|
17
17
|
|
18
|
+
def base_file_name
|
19
|
+
"#{backup["file_name_base"]}_#{hostname}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def hostname
|
23
|
+
%x{hostname -s}.chomp
|
24
|
+
end
|
25
|
+
|
18
26
|
private
|
19
27
|
|
20
28
|
attr_reader :config
|
21
29
|
|
30
|
+
def config_file
|
31
|
+
YAML.load_file(config_file_path)
|
32
|
+
rescue Errno::ENOENT
|
33
|
+
STDERR.puts "Please create a config file in #{config_file_path}"
|
34
|
+
STDERR.puts "\nIt should look like:\n\n#{File.read('config/config-example.yml')}"
|
35
|
+
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_file_path
|
40
|
+
"#{ENV['HOME']}/.config/backup_jenkins/config.yml"
|
41
|
+
end
|
22
42
|
end
|
23
43
|
end
|
@@ -1,4 +1,150 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BackupJenkins::AWS do
|
4
|
+
let(:config) { stub }
|
5
|
+
let(:s3_mocks) { stub(buckets: stub(:[] => stub(exists?: true), create: true)) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
BackupJenkins::Config.stub(:new).and_return(config)
|
9
|
+
|
10
|
+
config.stub(:aws).and_return({ "access_key" => "some_key", "secret" => "some_secret" })
|
11
|
+
config.stub(:backup).and_return({ "backups_to_keep" => 2 })
|
12
|
+
|
13
|
+
::AWS::S3.stub(:new).and_return(s3_mocks)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#setup_aws" do
|
17
|
+
after do
|
18
|
+
subject
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should instantiate an S3 object" do
|
22
|
+
::AWS::S3.should_receive(:new).and_return(s3_mocks)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "shuld create bucket" do
|
26
|
+
s3_mocks.buckets.should_receive(:[]).and_return(mock(exists?: false))
|
27
|
+
s3_mocks.buckets.should_receive(:create).and_return(mock(exists?: true))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#populate_files" do
|
32
|
+
it "should get the objects from backup_files and sort them" do
|
33
|
+
a = mock(key: 1)
|
34
|
+
b = mock(key: 2)
|
35
|
+
c = mock(key: 3)
|
36
|
+
|
37
|
+
subject.should_receive(:backup_files).and_return([b, c, a])
|
38
|
+
subject.populate_files.should == [a, b, c]
|
39
|
+
subject.instance_variable_get(:"@files").should == [a, b, c]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#backup_files" do
|
44
|
+
it "should return the right files" do
|
45
|
+
config.should_receive(:base_file_name).and_return("base_file_name")
|
46
|
+
objects = mock
|
47
|
+
objects.should_receive(:with_prefix).with("base_file_name").and_return([1, 2, 3])
|
48
|
+
subject.should_receive(:s3_files).and_return(objects)
|
49
|
+
|
50
|
+
subject.backup_files.should == [1, 2, 3]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#remove_old_files" do
|
55
|
+
before do
|
56
|
+
config.stub(:verbose).and_return(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should populate_files" do
|
60
|
+
subject.should_receive(:populate_files)
|
61
|
+
subject.should_receive(:do_remove_old_files)
|
62
|
+
subject.remove_old_files
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should print stuff if verbose" do
|
66
|
+
config.should_receive(:verbose).twice.and_return(true)
|
67
|
+
subject.stub(:populate_files)
|
68
|
+
subject.stub(:do_remove_old_files)
|
69
|
+
|
70
|
+
STDOUT.should_receive(:puts).with("Looking for old files...")
|
71
|
+
STDOUT.should_receive(:puts).with("Done.")
|
72
|
+
|
73
|
+
subject.remove_old_files
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#do_remove_old_files" do
|
78
|
+
it "should iterate over files_to_remove and call delete on each one" do
|
79
|
+
config.stub(:verbose).and_return(false)
|
80
|
+
|
81
|
+
file_1 = mock
|
82
|
+
file_2 = mock
|
83
|
+
|
84
|
+
file_1.should_receive(:delete)
|
85
|
+
file_2.should_receive(:delete)
|
86
|
+
|
87
|
+
subject.should_receive(:files_to_remove).and_return([file_1, file_2])
|
88
|
+
subject.do_remove_old_files
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should output that's removing a file if verbose" do
|
92
|
+
file_1 = mock(key: "filename", delete: true)
|
93
|
+
|
94
|
+
config.should_receive(:verbose).and_return(true)
|
95
|
+
subject.should_receive(:files_to_remove).and_return([file_1])
|
96
|
+
STDOUT.should_receive(:puts).with("Removing filename...")
|
97
|
+
|
98
|
+
subject.do_remove_old_files
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#files_to_remove" do
|
103
|
+
it "should get the last n files (where n is total number - keep)" do
|
104
|
+
subject.stub(:files).and_return(%w(a b c d e f g))
|
105
|
+
subject.files_to_remove.should == ["a", "b", "c", "d", "e"]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#upload_file" do
|
110
|
+
it "should create a file" do
|
111
|
+
config.stub(:verbose).and_return(false)
|
112
|
+
objects = mock
|
113
|
+
objects.should_receive(:create).with("filename", "file").and_return(
|
114
|
+
mock(class: AWS::S3::S3Object)
|
115
|
+
)
|
116
|
+
subject.should_receive(:s3_files).and_return(objects)
|
117
|
+
|
118
|
+
subject.upload_file("filename", "file")
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should print stuff in verbose" do
|
122
|
+
config.should_receive(:verbose).twice.and_return(true)
|
123
|
+
|
124
|
+
objects = mock
|
125
|
+
objects.stub(:create).with("filename", "file").and_return(mock(class: AWS::S3::S3Object))
|
126
|
+
subject.stub(:s3_files).and_return(objects)
|
127
|
+
|
128
|
+
STDOUT.should_receive(:puts).with("About to upload filename...")
|
129
|
+
STDOUT.should_receive(:puts).with("Done")
|
130
|
+
|
131
|
+
subject.upload_file("filename", "file")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should raise exception if no s3 object is created" do
|
135
|
+
config.stub(:verbose).and_return(false)
|
136
|
+
|
137
|
+
objects = mock
|
138
|
+
objects.stub(:create).with("filename", "file").and_return(mock)
|
139
|
+
subject.stub(:s3_files).and_return(objects)
|
140
|
+
|
141
|
+
expect{ subject.upload_file("filename", "file")}.to raise_error \
|
142
|
+
::BackupJenkins::AWS::UploadFileError
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#s3_files" do
|
147
|
+
after { subject.send(:s3_files) }
|
148
|
+
it { subject.should_receive(:bucket).and_return(mock(objects: mock)) }
|
149
|
+
end
|
4
150
|
end
|
@@ -1,4 +1,216 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BackupJenkins::Backup do
|
4
|
+
let(:config) { mock }
|
5
|
+
|
6
|
+
before do
|
7
|
+
BackupJenkins::Config.stub(:new).and_return(config)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
it "should assign @config" do
|
12
|
+
subject.instance_variable_get(:"@config").should == config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#backup_directory" do
|
17
|
+
let(:backup) { { "dir_base" => "/path/to/some/dir_base" } }
|
18
|
+
|
19
|
+
it "should return the dir base + the base file name + time stamp" do
|
20
|
+
config.should_receive(:backup).and_return(backup)
|
21
|
+
config.should_receive(:base_file_name).and_return("filename")
|
22
|
+
subject.should_receive(:timestamp).and_return("timestamp")
|
23
|
+
|
24
|
+
subject.backup_directory.should == "/path/to/some/dir_base/filename_timestamp"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should get data only once" do
|
28
|
+
config.should_receive(:backup).once.and_return(backup)
|
29
|
+
config.should_receive(:base_file_name).once.and_return("filename")
|
30
|
+
subject.should_receive(:timestamp).once.and_return("timestamp")
|
31
|
+
|
32
|
+
subject.backup_directory
|
33
|
+
subject.backup_directory
|
34
|
+
subject.backup_directory
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#copy_files" do
|
39
|
+
before do
|
40
|
+
subject.stub(:plugin_files).and_return("plugin_files")
|
41
|
+
subject.stub(:user_content_files).and_return("user_content_files")
|
42
|
+
subject.stub(:jobs_files).and_return("jobs_files")
|
43
|
+
|
44
|
+
subject.stub(:create_dir_and_copy)
|
45
|
+
end
|
46
|
+
|
47
|
+
after { subject.copy_files }
|
48
|
+
|
49
|
+
it { subject.should_receive(:create_dir_and_copy).with("plugin_files") }
|
50
|
+
it { subject.should_receive(:create_dir_and_copy).with("user_content_files") }
|
51
|
+
it { subject.should_receive(:create_dir_and_copy).with("jobs_files") }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#create_dir_and_copy" do
|
55
|
+
it "should iterate over filenames and call create_dir_and_copy_impl with them" do
|
56
|
+
subject.should_receive(:create_dir_and_copy_impl).with("a")
|
57
|
+
subject.should_receive(:create_dir_and_copy_impl).with("b")
|
58
|
+
subject.should_receive(:create_dir_and_copy_impl).with("c")
|
59
|
+
|
60
|
+
subject.create_dir_and_copy(%w(a b c))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#create_dir_and_copy_impl" do
|
65
|
+
before do
|
66
|
+
FileTest.stub(:file?).and_return(true)
|
67
|
+
FileUtils.stub(:mkdir_p)
|
68
|
+
FileUtils.stub(:cp)
|
69
|
+
config.stub(:verbose).and_return(false)
|
70
|
+
subject.stub(:new_file_path).and_return("/this/is/a/new/path/to_file")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should get the new file path of the file" do
|
74
|
+
subject.should_receive(:new_file_path)
|
75
|
+
subject.create_dir_and_copy_impl("filename")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should create directory new_directory" do
|
79
|
+
FileUtils.should_receive(:mkdir_p).with("/this/is/a/new/path", verbose: false)
|
80
|
+
subject.create_dir_and_copy_impl("filename")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should copy old file to new file" do
|
84
|
+
FileUtils.should_receive(:cp).with("filename", "/this/is/a/new/path/to_file", verbose: false)
|
85
|
+
subject.create_dir_and_copy_impl("filename")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should raise error if file to copy from doesn't exist" do
|
89
|
+
FileTest.should_receive(:file?).and_return(false)
|
90
|
+
expect{ subject.create_dir_and_copy_impl("filename") }.to raise_error
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#create_tarball" do
|
95
|
+
before do
|
96
|
+
Dir.stub(:chdir)
|
97
|
+
FileTest.stub(:file?).and_return(true)
|
98
|
+
|
99
|
+
config.stub(:verbose).and_return(false)
|
100
|
+
|
101
|
+
subject.stub(:`)
|
102
|
+
subject.stub(:backup_directory).and_return("directory")
|
103
|
+
subject.stub(:tar_options).and_return("options")
|
104
|
+
end
|
105
|
+
|
106
|
+
context do
|
107
|
+
after { subject.create_tarball }
|
108
|
+
it { Dir.should_receive(:chdir).with("directory") }
|
109
|
+
it { subject.should_receive(:`).with("tar options directory.tar.bz2 .") }
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should raise error if file doesn't exist" do
|
113
|
+
FileTest.should_receive(:file?).and_return(false)
|
114
|
+
expect{ subject.create_tarball }.to raise_error
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#do_backup" do
|
119
|
+
before do
|
120
|
+
FileTest.stub(:directory?).and_return(false)
|
121
|
+
subject.stub(:backup_directory).and_return("backup_directory")
|
122
|
+
subject.stub(:copy_files)
|
123
|
+
subject.stub(:create_tarball)
|
124
|
+
subject.stub(:remove_temporary_files)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should raise error if backup directory exists already" do
|
128
|
+
FileTest.should_receive(:directory?).and_return(true)
|
129
|
+
expect{ subject.do_backup }.to raise_error
|
130
|
+
end
|
131
|
+
|
132
|
+
context do
|
133
|
+
after { subject.do_backup }
|
134
|
+
|
135
|
+
it { subject.should_receive(:copy_files) }
|
136
|
+
it { subject.should_receive(:create_tarball) }
|
137
|
+
it { subject.should_receive(:remove_temporary_files) }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#jobs_files" do
|
142
|
+
before { config.stub(:jenkins).and_return({ "home" => "home" }) }
|
143
|
+
|
144
|
+
it "should return the config.xml and nextBuildNumber files in job directories" do
|
145
|
+
subject.should_receive(:`).
|
146
|
+
with("find home -maxdepth 3 -name config.xml -or -name nextBuildNumber").
|
147
|
+
and_return("file1\nfile2\nfile3")
|
148
|
+
subject.jobs_files.should == %w(file1 file2 file3)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#new_file_path" do
|
153
|
+
it "should return backup_directory/something" do
|
154
|
+
subject.should_receive(:backup_directory).and_return("backup_directory")
|
155
|
+
config.should_receive(:jenkins).and_return({ "home" => "some_nice_house"})
|
156
|
+
|
157
|
+
subject.new_file_path("some_nice_house/and/then/a/room").should == "backup_directory/and/then/a/room"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#plugin_files" do
|
162
|
+
before { config.stub(:jenkins).and_return({ "home" => "home" }) }
|
163
|
+
|
164
|
+
it "returns a collection of directories including all the files that have .jpi" do
|
165
|
+
Dir.should_receive(:[]).with("home/plugins/*.jpi").and_return(["jpi"])
|
166
|
+
Dir.should_receive(:[]).with("home/plugins/*.jpi.pinned").and_return(["pinned"])
|
167
|
+
Dir.should_receive(:[]).with("home/plugins/*.jpi.disabled").and_return(["disabled"])
|
168
|
+
|
169
|
+
subject.plugin_files.should == %w(jpi pinned disabled)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "#remove_temporary_files" do
|
174
|
+
before do
|
175
|
+
subject.should_receive(:backup_directory).and_return("backup_directory")
|
176
|
+
config.stub(:verbose).and_return(false)
|
177
|
+
end
|
178
|
+
|
179
|
+
after { subject.remove_temporary_files }
|
180
|
+
it { FileUtils.should_receive(:rm_rf).with("backup_directory", verbose: false) }
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "#tar_options" do
|
184
|
+
it "should be jcf" do
|
185
|
+
config.should_receive(:verbose).and_return(false)
|
186
|
+
subject.tar_options == "jcf"
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should be vjcf" do
|
190
|
+
config.should_receive(:verbose).and_return(true)
|
191
|
+
subject.tar_options == "vjcf"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#tarball_filename" do
|
196
|
+
before { subject.should_receive(:backup_directory).and_return("backup_directory") }
|
197
|
+
it { subject.tarball_filename.should == "backup_directory.tar.bz2"}
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "#timestamp" do
|
201
|
+
it "should return the current time with the desired timestamp from the config" do
|
202
|
+
config.stub(:backup).and_return("timestamp" => "%Y%m%d_%H%M")
|
203
|
+
Time.stub(:now).and_return(Time.parse("2013/01/01 12:34PM"))
|
204
|
+
subject.send(:timestamp).should == "20130101_1234"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "#user_content_files" do
|
209
|
+
before { config.stub(:jenkins).and_return({ "home" => "home" }) }
|
210
|
+
|
211
|
+
it "should return files inside the userContent directory" do
|
212
|
+
Dir.should_receive(:[]).with("home/userContent/*").and_return(["my_file"])
|
213
|
+
subject.user_content_files.should == %w(my_file)
|
214
|
+
end
|
215
|
+
end
|
4
216
|
end
|
@@ -1,4 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BackupJenkins::CLI do
|
4
|
+
let(:aws) { stub }
|
5
|
+
let(:backup) { stub }
|
6
|
+
let(:config) { stub }
|
7
|
+
|
8
|
+
before do
|
9
|
+
BackupJenkins::AWS.stub(:new).and_return(aws)
|
10
|
+
BackupJenkins::Backup.stub(:new).and_return(backup)
|
11
|
+
BackupJenkins::Config.stub(:new).and_return(config)
|
12
|
+
|
13
|
+
File.stub(:open).and_return(:IO)
|
14
|
+
|
15
|
+
backup.stub(:do_backup)
|
16
|
+
backup.stub(:tarball_filename).and_return("tarball_filename")
|
17
|
+
|
18
|
+
aws.stub(:upload_file)
|
19
|
+
aws.stub(:remove_old_files)
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
BackupJenkins::CLI.run
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".run" do
|
27
|
+
it { BackupJenkins::AWS.should_receive(:new).with(config) }
|
28
|
+
it { BackupJenkins::Backup.should_receive(:new).with(config) }
|
29
|
+
it { BackupJenkins::Config.should_receive(:new) }
|
30
|
+
it { backup.should_receive(:do_backup) }
|
31
|
+
it { backup.should_receive(:tarball_filename).and_return("tarball_filename") }
|
32
|
+
it { aws.should_receive(:upload_file).with("tarball_filename", :IO) }
|
33
|
+
it { aws.should_receive(:remove_old_files) }
|
34
|
+
end
|
4
35
|
end
|
@@ -3,19 +3,51 @@ require 'tempfile'
|
|
3
3
|
|
4
4
|
describe BackupJenkins::Config do
|
5
5
|
before do
|
6
|
-
|
7
|
-
"aws" => {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
config = {
|
7
|
+
"aws" => { "access_key" => "some_key", "secret" => "some_secret" },
|
8
|
+
"backup" => { "file_name_base" => "jenkins" }
|
9
|
+
}
|
10
|
+
|
11
|
+
YAML.stub(:load_file).and_return(config)
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
15
|
-
|
14
|
+
it { expect{ subject.foo }.to raise_error NoMethodError }
|
15
|
+
it { should be_respond_to(:aws) }
|
16
|
+
it { should_not be_respond_to(:foo) }
|
17
|
+
it { subject.aws["access_key"].should == "some_key" }
|
18
|
+
it { subject.aws["secret"].should == "some_secret" }
|
19
|
+
|
20
|
+
describe "#base_file_name" do
|
21
|
+
before { subject.stub(:hostname).and_return("hostname") }
|
22
|
+
it { subject.base_file_name.should == "jenkins_hostname" }
|
16
23
|
end
|
17
24
|
|
18
|
-
|
19
|
-
subject.
|
25
|
+
describe "#hostname" do
|
26
|
+
after { subject.hostname.should == 'hostname' }
|
27
|
+
it { subject.should_receive(:`).with("hostname -s").and_return("hostname\n") }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#config_file" do
|
31
|
+
it "should load file" do
|
32
|
+
YAML.should_receive(:load_file).and_return("configuration")
|
33
|
+
subject.instance_variable_get(:"@config").should == "configuration"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should exit with non 0 on error" do
|
37
|
+
YAML.should_receive(:load_file).and_raise(Errno::ENOENT)
|
38
|
+
expect{ subject }.to raise_error SystemExit
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should print some helpful text if config file doesn't exist" do
|
42
|
+
subject.should_receive(:config_file_path).twice.and_return("config")
|
43
|
+
|
44
|
+
YAML.should_receive(:load_file).and_raise(Errno::ENOENT)
|
45
|
+
File.should_receive(:read).and_return("sample")
|
46
|
+
|
47
|
+
STDERR.should_receive(:puts).with("Please create a config file in config")
|
48
|
+
STDERR.should_receive(:puts).with("\nIt should look like:\n\nsample")
|
49
|
+
|
50
|
+
expect{ subject.send(:config_file) }.to raise_error SystemExit
|
51
|
+
end
|
20
52
|
end
|
21
53
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backup_jenkins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-11-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rake
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: pry-debugger
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: pry-stack_explorer
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,7 +69,12 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
description: Simple Jenkins config and plugin backup to S3
|
59
79
|
email:
|
60
80
|
- jcmuller@gmail.com
|
@@ -67,12 +87,13 @@ files:
|
|
67
87
|
- .rspec
|
68
88
|
- .travis.yml
|
69
89
|
- Gemfile
|
90
|
+
- Guardfile
|
70
91
|
- LICENSE
|
71
92
|
- README.md
|
72
93
|
- Rakefile
|
73
94
|
- backup_jenkins.gemspec
|
74
95
|
- bin/backup_jenkins
|
75
|
-
- config/config-
|
96
|
+
- config/config-example.yml
|
76
97
|
- lib/backup_jenkins.rb
|
77
98
|
- lib/backup_jenkins/aws.rb
|
78
99
|
- lib/backup_jenkins/backup.rb
|
@@ -96,21 +117,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
117
|
- - ! '>='
|
97
118
|
- !ruby/object:Gem::Version
|
98
119
|
version: '0'
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
hash: 2193945610003715727
|
99
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
124
|
none: false
|
101
125
|
requirements:
|
102
126
|
- - ! '>='
|
103
127
|
- !ruby/object:Gem::Version
|
104
128
|
version: '0'
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
hash: 2193945610003715727
|
105
132
|
requirements: []
|
106
133
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
134
|
+
rubygems_version: 1.8.24
|
108
135
|
signing_key:
|
109
136
|
specification_version: 3
|
110
137
|
summary: This gem allows you to get a backup instance of jenkins up and running pretty
|
111
138
|
quickly
|
112
139
|
test_files:
|
140
|
+
- spec/lib/backup_jenkins/aws_spec.rb
|
113
141
|
- spec/lib/backup_jenkins/backup_spec.rb
|
114
142
|
- spec/lib/backup_jenkins/cli_spec.rb
|
115
143
|
- spec/lib/backup_jenkins/config_spec.rb
|
116
|
-
- spec/lib/backup_jenkins/aws_spec.rb
|