backup_jenkins 0.0.5 → 0.0.7
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 +4 -5
- data/README.md +15 -14
- data/backup_jenkins.gemspec +1 -4
- data/lib/backup_jenkins/aws.rb +51 -16
- data/lib/backup_jenkins/backup.rb +28 -0
- data/lib/backup_jenkins/cli.rb +173 -8
- data/lib/backup_jenkins/config.rb +9 -5
- data/lib/backup_jenkins/formatter.rb +37 -0
- data/lib/backup_jenkins/version.rb +1 -1
- data/lib/backup_jenkins.rb +9 -6
- data/spec/lib/backup_jenkins/aws_spec.rb +20 -45
- data/spec/lib/backup_jenkins/backup_spec.rb +13 -0
- data/spec/lib/backup_jenkins/cli_spec.rb +18 -3
- data/spec/lib/backup_jenkins/config_spec.rb +2 -2
- data/spec/lib/backup_jenkins/formatter_spec.rb +61 -0
- metadata +8 -5
data/Gemfile
CHANGED
@@ -5,19 +5,18 @@ gemspec
|
|
5
5
|
|
6
6
|
group :development do
|
7
7
|
gem "guard"
|
8
|
-
gem "guard-rspec"
|
9
8
|
gem "guard-bundler"
|
10
|
-
gem "
|
11
|
-
gem "rb-fsevent", :require => false
|
9
|
+
gem "guard-rspec"
|
12
10
|
gem "rb-fchange", :require => false
|
11
|
+
gem "rb-fsevent", :require => false
|
12
|
+
gem "rb-inotify", :require => false
|
13
13
|
gem "terminal-notifier-guard"
|
14
14
|
end
|
15
15
|
|
16
16
|
group :test do
|
17
|
+
gem "ci_reporter"
|
17
18
|
gem "rake"
|
18
19
|
gem "rspec"
|
19
|
-
gem "ci_reporter"
|
20
20
|
gem "simplecov"
|
21
21
|
gem "simplecov-rcov"
|
22
|
-
gem "flog"
|
23
22
|
end
|
data/README.md
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
# BackupJenkins
|
2
|
-
[](https://codeclimate.com/github/jcmuller/
|
4
|
-
[](http://travis-ci.org/jcmuller/backup_jenkins)
|
3
|
+
[](https://codeclimate.com/github/jcmuller/backup_jenkins)
|
4
|
+
[](https://gemnasium.com/jcmuller/backup_jenkins)
|
5
5
|
|
6
|
-
|
6
|
+
This gem provides `backup_jenkins`, which provided with a correctly configured `config.yml`
|
7
|
+
located on `~/.config/backup_jenkins/` will backup your job configurations, next build number,
|
8
|
+
global configuration and plugins up to your Amazon AWS S3 account.
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
Add this line to your application's Gemfile:
|
11
|
-
|
12
|
-
gem 'backup_jenkins'
|
10
|
+
### Prerequisites
|
13
11
|
|
14
|
-
|
12
|
+
* Amazon AWS S3 account (you need to provide the user and secret keys)
|
13
|
+
* Jenkins installation
|
14
|
+
* Backup volume with lots of space
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
Or install it yourself as:
|
16
|
+
## Installation
|
19
17
|
|
20
18
|
$ gem install backup_jenkins
|
21
19
|
|
22
20
|
## Usage
|
23
21
|
|
24
|
-
|
22
|
+
$ backup_jenkins
|
23
|
+
|
24
|
+
The first time you run `backup_jenkins`, it shows you a sample configuration file which you
|
25
|
+
should copy into the appropriate location and fill in with your information.
|
25
26
|
|
26
27
|
## Contributing
|
27
28
|
|
data/backup_jenkins.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["jcmuller@gmail.com"]
|
7
7
|
gem.description = %{Simple Jenkins config and plugin backup to S3}
|
8
8
|
gem.summary = %q{This gem allows you to get a backup instance of jenkins up and running pretty quickly}
|
9
|
-
gem.homepage = "http://github.com/jcmuller/
|
9
|
+
gem.homepage = "http://github.com/jcmuller/backup_jenkins"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -16,8 +16,5 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = BackupJenkins::VERSION
|
17
17
|
|
18
18
|
gem.add_dependency("aws-sdk")
|
19
|
-
|
20
19
|
gem.add_development_dependency("rake")
|
21
|
-
#gem.add_development_dependency("pry-debugger")
|
22
|
-
#gem.add_development_dependency("pry-stack_explorer")
|
23
20
|
end
|
data/lib/backup_jenkins/aws.rb
CHANGED
@@ -2,28 +2,49 @@ module BackupJenkins
|
|
2
2
|
class AWS
|
3
3
|
class UploadFileError < StandardError; end
|
4
4
|
|
5
|
+
include BackupJenkins::Formatter
|
6
|
+
|
5
7
|
def initialize(config = Config.new)
|
6
8
|
@config = config
|
7
9
|
setup_aws
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
@files.sort!{ |a, b| a.key <=> b.key }
|
14
|
-
end
|
15
|
-
|
16
|
-
def backup_files
|
17
|
-
s3_files.with_prefix(config.base_file_name)
|
12
|
+
def list_backup_files
|
13
|
+
file_hashes = backup_files_for_all_hosts.map{ |f| s3_object_to_hash(f) }
|
14
|
+
format_backup_file_data(file_hashes)
|
18
15
|
end
|
19
16
|
|
20
17
|
def remove_old_files
|
21
18
|
puts "Looking for old files..." if config.verbose
|
22
|
-
populate_files
|
23
19
|
do_remove_old_files
|
24
20
|
puts "Done." if config.verbose
|
25
21
|
end
|
26
22
|
|
23
|
+
def upload_file(filename, file)
|
24
|
+
puts "About to upload #{filename}..." if config.verbose
|
25
|
+
new_file = s3_files.create(filename, file)
|
26
|
+
puts "Done" if config.verbose
|
27
|
+
raise UploadFileError unless new_file.class == ::AWS::S3::S3Object
|
28
|
+
end
|
29
|
+
|
30
|
+
def download_file(filename)
|
31
|
+
remote_file = bucket.objects[filename]
|
32
|
+
|
33
|
+
File.open(filename, 'w') do |file|
|
34
|
+
count = 0
|
35
|
+
remote_file.read do |chunk|
|
36
|
+
file.write(chunk)
|
37
|
+
print "." if count % 512 == 0
|
38
|
+
count += 1
|
39
|
+
end
|
40
|
+
puts "."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
attr_reader :config, :bucket
|
47
|
+
|
27
48
|
def do_remove_old_files
|
28
49
|
files_to_remove.each do |file|
|
29
50
|
puts "Removing #{file.key}..." if config.verbose
|
@@ -36,16 +57,17 @@ module BackupJenkins
|
|
36
57
|
files - files.last(config.backup["backups_to_keep"])
|
37
58
|
end
|
38
59
|
|
39
|
-
def
|
40
|
-
|
41
|
-
new_file = s3_files.create(filename, file)
|
42
|
-
puts "Done" if config.verbose
|
43
|
-
raise UploadFileError unless new_file.class == ::AWS::S3::S3Object
|
60
|
+
def files
|
61
|
+
@files ||= backup_files_for_this_host.sort{ |a, b| a.key <=> b.key }
|
44
62
|
end
|
45
63
|
|
46
|
-
|
64
|
+
def backup_files_for_this_host
|
65
|
+
s3_files.with_prefix(config.base_file_name)
|
66
|
+
end
|
47
67
|
|
48
|
-
|
68
|
+
def backup_files_for_all_hosts
|
69
|
+
s3_files.with_prefix(config.backup["file_name_base"])
|
70
|
+
end
|
49
71
|
|
50
72
|
def setup_aws
|
51
73
|
s3 = initialize_s3_object
|
@@ -61,6 +83,19 @@ module BackupJenkins
|
|
61
83
|
)
|
62
84
|
end
|
63
85
|
|
86
|
+
# Returns a structure like:
|
87
|
+
# [
|
88
|
+
# { :key => "jenkins_berman_20121107_1721.tar.bz2", :content_length => 88762813 },
|
89
|
+
# { :key => "jenkins_berman_20121107_1745.tar.bz2", :content_length => 88762572 }
|
90
|
+
# ]
|
91
|
+
def s3_object_to_hash(s3_object)
|
92
|
+
{}.tap do |hash|
|
93
|
+
[:key, :content_length, :metadata].each do |key|
|
94
|
+
hash[key] = s3_object.send(key)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
64
99
|
def s3_files
|
65
100
|
bucket.objects
|
66
101
|
end
|
@@ -2,6 +2,8 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
module BackupJenkins
|
4
4
|
class Backup
|
5
|
+
include BackupJenkins::Formatter
|
6
|
+
|
5
7
|
def initialize(config = Config.new)
|
6
8
|
@config = config
|
7
9
|
end
|
@@ -16,6 +18,10 @@ module BackupJenkins
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
def list_local_files
|
22
|
+
format_backup_file_data(backup_files)
|
23
|
+
end
|
24
|
+
|
19
25
|
def create_dir_and_copy_impl(file_name)
|
20
26
|
raise "file '#{file_name}' does not exist" unless FileTest.file?(file_name)
|
21
27
|
|
@@ -37,6 +43,19 @@ module BackupJenkins
|
|
37
43
|
|
38
44
|
create_tarball
|
39
45
|
remove_temporary_files
|
46
|
+
rescue Interrupt
|
47
|
+
puts "Cleaning up..."
|
48
|
+
clean_up
|
49
|
+
end
|
50
|
+
|
51
|
+
def clean_up
|
52
|
+
puts "Removing #{backup_directory}"
|
53
|
+
remove_temporary_files
|
54
|
+
|
55
|
+
puts "Removing #{tarball_filename}"
|
56
|
+
FileUtils.rm_rf(tarball_filename)
|
57
|
+
rescue Errno::ENOENT
|
58
|
+
puts e
|
40
59
|
end
|
41
60
|
|
42
61
|
def copy_files
|
@@ -86,5 +105,14 @@ module BackupJenkins
|
|
86
105
|
def timestamp
|
87
106
|
Time.now.strftime(config.backup["timestamp"])
|
88
107
|
end
|
108
|
+
|
109
|
+
def backup_files
|
110
|
+
Dir["#{config.backup["dir_base"]}/#{config.base_file_name}_*tar.bz2"].map do |file|
|
111
|
+
{
|
112
|
+
:key => file.gsub(%r{#{config.backup["dir_base"]}/}, ''),
|
113
|
+
:content_length => File.size(file)
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
89
117
|
end
|
90
118
|
end
|
data/lib/backup_jenkins/cli.rb
CHANGED
@@ -2,18 +2,183 @@ module BackupJenkins
|
|
2
2
|
class CLI
|
3
3
|
class << self
|
4
4
|
def run
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
cli = self.new
|
6
|
+
cli.parse_options
|
7
|
+
cli.run
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_options
|
12
|
+
options.each do |opt, arg|
|
13
|
+
case opt
|
14
|
+
when '--config'
|
15
|
+
override_config_file_with(arg)
|
16
|
+
when '--download'
|
17
|
+
download_file(arg)
|
18
|
+
when '--help'
|
19
|
+
show_help
|
20
|
+
when '--license'
|
21
|
+
show_license
|
22
|
+
when '--list'
|
23
|
+
list_remote_backups
|
24
|
+
when '--list-local'
|
25
|
+
list_local_backups
|
26
|
+
when '--only-local'
|
27
|
+
@only_local = true
|
28
|
+
when '--verbose'
|
29
|
+
override_config_file_with_option("verbose" => true)
|
30
|
+
when '--version'
|
31
|
+
show_version
|
32
|
+
end
|
33
|
+
end
|
34
|
+
rescue GetoptLong::MissingArgument
|
35
|
+
# GetoptLong Already outputs the error.
|
36
|
+
puts "\n"
|
37
|
+
show_help
|
38
|
+
end
|
39
|
+
|
40
|
+
def options_possible
|
41
|
+
[
|
42
|
+
[
|
43
|
+
'--config', '-c', GetoptLong::REQUIRED_ARGUMENT,
|
44
|
+
'Override config file location. Path to this file is required.'
|
45
|
+
],
|
46
|
+
[
|
47
|
+
'--download', '-d', GetoptLong::REQUIRED_ARGUMENT,
|
48
|
+
'Download a backup file to current directory. File name is required.'
|
49
|
+
],
|
50
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT, 'Print this message.'],
|
51
|
+
['--license', '-L', GetoptLong::NO_ARGUMENT, 'Print license.'],
|
52
|
+
['--list', '-l', GetoptLong::NO_ARGUMENT, 'List backups available on S3.'],
|
53
|
+
['--list-local', '-o', GetoptLong::NO_ARGUMENT, 'List local backups available.'],
|
54
|
+
['--only-local', '-O', GetoptLong::NO_ARGUMENT, 'Only create local backup file.'],
|
55
|
+
['--verbose', '-v', GetoptLong::NO_ARGUMENT, 'Be verbose. This overrides config file.'],
|
56
|
+
['--version', '-V', GetoptLong::NO_ARGUMENT, 'Print version number and exit,']
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
def run
|
61
|
+
backup.do_backup
|
62
|
+
|
63
|
+
full_filename = backup.tarball_filename
|
64
|
+
filename = File.basename(full_filename)
|
65
|
+
|
66
|
+
aws.upload_file(filename, File.open(full_filename)) unless @only_local
|
67
|
+
aws.remove_old_files # Clean up!
|
68
|
+
rescue Interrupt
|
69
|
+
backup.clean_up
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def config
|
75
|
+
@config ||= BackupJenkins::Config.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def aws
|
79
|
+
@aws ||= BackupJenkins::AWS.new(config)
|
80
|
+
end
|
81
|
+
|
82
|
+
def backup
|
83
|
+
@backup ||= BackupJenkins::Backup.new(config)
|
84
|
+
end
|
85
|
+
|
86
|
+
def options
|
87
|
+
@options ||= GetoptLong.new(*options_possible.map{ |o| o.first(3) })
|
88
|
+
end
|
89
|
+
|
90
|
+
# Entry points
|
91
|
+
|
92
|
+
def show_help
|
93
|
+
STDOUT.puts help_info
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
|
97
|
+
def show_version
|
98
|
+
STDOUT.puts version_info
|
99
|
+
exit
|
100
|
+
end
|
101
|
+
|
102
|
+
def show_license
|
103
|
+
STDOUT.puts license_info
|
104
|
+
exit
|
105
|
+
end
|
106
|
+
|
107
|
+
def list_remote_backups
|
108
|
+
STDOUT.puts aws.list_backup_files
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
|
112
|
+
def list_local_backups
|
113
|
+
STDOUT.puts backup.list_local_files
|
114
|
+
exit
|
115
|
+
end
|
116
|
+
|
117
|
+
def download_file(filename)
|
118
|
+
aws.download_file(filename)
|
119
|
+
exit
|
120
|
+
end
|
121
|
+
|
122
|
+
def override_config_file_with(config_file_name)
|
123
|
+
raise "File not found or not readable" unless File.readable?(config_file_name)
|
124
|
+
@config = BackupJenkins::Config.new(config_file_name)
|
125
|
+
end
|
126
|
+
|
127
|
+
def override_config_file_with_option(options = {})
|
128
|
+
config.override(options)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Data
|
132
|
+
|
133
|
+
def license_info
|
134
|
+
"#{File.read(license_file_path)}\n\n"
|
135
|
+
end
|
136
|
+
|
137
|
+
def license_file_path
|
138
|
+
File.expand_path("../../..//LICENSE", __FILE__)
|
139
|
+
end
|
8
140
|
|
9
|
-
|
141
|
+
def version_info
|
142
|
+
<<-EOV
|
143
|
+
backup_jenkins (#{BackupJenkins::VERSION})
|
144
|
+
https://github.com/jcmuller/backup_jenkins
|
145
|
+
(c) 2012 Juan C. Muller
|
146
|
+
Work on this has been proudly backed by ChallengePost, Inc.
|
147
|
+
EOV
|
148
|
+
end
|
10
149
|
|
11
|
-
|
12
|
-
|
150
|
+
def help_info
|
151
|
+
<<-EOH
|
152
|
+
Usage: #{File.basename($0)} [options]
|
153
|
+
[#{options_possible.map{ |o| short_hand_option(o)}.join('], [')}]
|
154
|
+
|
155
|
+
Options:
|
156
|
+
#{option_details}
|
157
|
+
|
158
|
+
#{version_info}
|
159
|
+
EOH
|
160
|
+
end
|
13
161
|
|
14
|
-
|
15
|
-
|
162
|
+
def short_hand_option(option)
|
163
|
+
if option[2] == GetoptLong::REQUIRED_ARGUMENT
|
164
|
+
[option[0], option[1]].join('|') << " argument"
|
165
|
+
else
|
166
|
+
[option[0], option[1]].join('|')
|
16
167
|
end
|
17
168
|
end
|
169
|
+
|
170
|
+
def option_details
|
171
|
+
<<-EOO
|
172
|
+
#{options_possible.map{ |o| expand_option(o) }.join("\n")}
|
173
|
+
EOO
|
174
|
+
end
|
175
|
+
|
176
|
+
def longest_width
|
177
|
+
@max_width ||= options_possible.map{ |o| o[0] }.max{ |a, b| a.length <=> b.length }.length
|
178
|
+
end
|
179
|
+
|
180
|
+
def expand_option(option)
|
181
|
+
sprintf(" %-#{longest_width + 6}s %s", option.first(2).join(', '), option[3])
|
182
|
+
end
|
18
183
|
end
|
19
184
|
end
|
@@ -2,8 +2,8 @@ module BackupJenkins
|
|
2
2
|
class Config
|
3
3
|
attr_reader :s3
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
@config = config_file
|
5
|
+
def initialize(path = default_config_file_path)
|
6
|
+
@config = config_file(path)
|
7
7
|
end
|
8
8
|
|
9
9
|
def method_missing(meth, *args, &block)
|
@@ -23,20 +23,24 @@ module BackupJenkins
|
|
23
23
|
%x{hostname -s}.chomp
|
24
24
|
end
|
25
25
|
|
26
|
+
def override(options = {})
|
27
|
+
@config.merge!(options)
|
28
|
+
end
|
29
|
+
|
26
30
|
private
|
27
31
|
|
28
32
|
attr_reader :config
|
29
33
|
|
30
|
-
def config_file
|
34
|
+
def config_file(config_file_path)
|
31
35
|
YAML.load_file(config_file_path)
|
32
36
|
rescue Errno::ENOENT
|
33
|
-
STDERR.puts "Please create a config file in #{
|
37
|
+
STDERR.puts "Please create a config file in #{default_config_file_path}"
|
34
38
|
STDERR.puts "\nIt should look like:\n\n#{config_file_example}"
|
35
39
|
|
36
40
|
exit 1
|
37
41
|
end
|
38
42
|
|
39
|
-
def
|
43
|
+
def default_config_file_path
|
40
44
|
"#{ENV['HOME']}/.config/backup_jenkins/config.yml"
|
41
45
|
end
|
42
46
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module BackupJenkins
|
2
|
+
module Formatter
|
3
|
+
|
4
|
+
# Assumes that filenames are ordered already
|
5
|
+
# Requires a structure like:
|
6
|
+
# [
|
7
|
+
# { :key => "jenkins_berman_20121107_1721.tar.bz2", :content_length => 88762813 },
|
8
|
+
# { :key => "jenkins_berman_20121107_1745.tar.bz2", :content_length => 88762572 }
|
9
|
+
# ]
|
10
|
+
def format_backup_file_data(file_hashes)
|
11
|
+
by_host = {}
|
12
|
+
file_hashes.each do |file_hash|
|
13
|
+
(date, host, key) = extract_data_from_filename(file_hash[:key])
|
14
|
+
by_host[host] ||= []
|
15
|
+
by_host[host].push([date, key, file_hash[:content_length] / 2.0**20])
|
16
|
+
end
|
17
|
+
|
18
|
+
"".tap do |output|
|
19
|
+
by_host.each do |host, data|
|
20
|
+
output << host.capitalize << ":" << $/
|
21
|
+
data.each do |datum|
|
22
|
+
output << sprintf(" - %s key: %s (%0.2f MB)#{$/}", *datum)
|
23
|
+
end
|
24
|
+
output << $/
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_data_from_filename(filename)
|
30
|
+
sans_base = filename.gsub(/#{config.backup["file_name_base"]}_/, '').gsub(/\.tar\.bz2/, '')
|
31
|
+
(hostname, date, time) = sans_base.split("_")
|
32
|
+
formatted_date = Time.parse(date << time).strftime("%Y/%m/%d %H:%M")
|
33
|
+
[formatted_date, hostname, filename]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/backup_jenkins.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'yaml'
|
3
2
|
require 'aws'
|
3
|
+
require 'getoptlong'
|
4
|
+
require 'time'
|
5
|
+
require 'yaml'
|
4
6
|
|
5
7
|
module BackupJenkins
|
6
|
-
autoload :AWS,
|
7
|
-
autoload :Backup,
|
8
|
-
autoload :CLI,
|
9
|
-
autoload :Config,
|
10
|
-
autoload :
|
8
|
+
autoload :AWS, 'backup_jenkins/aws'
|
9
|
+
autoload :Backup, 'backup_jenkins/backup'
|
10
|
+
autoload :CLI, 'backup_jenkins/cli'
|
11
|
+
autoload :Config, 'backup_jenkins/config'
|
12
|
+
autoload :Formatter, 'backup_jenkins/formatter'
|
13
|
+
autoload :VERSION, 'backup_jenkins/version'
|
11
14
|
end
|
@@ -8,7 +8,7 @@ describe BackupJenkins::AWS do
|
|
8
8
|
BackupJenkins::Config.stub(:new).and_return(config)
|
9
9
|
|
10
10
|
config.stub(:aws).and_return({ "access_key" => "some_key", "secret" => "some_secret" })
|
11
|
-
config.stub(:backup).and_return({ "backups_to_keep" => 2 })
|
11
|
+
config.stub(:backup).and_return({ "backups_to_keep" => 2, "file_name_base" => "jenkins" })
|
12
12
|
|
13
13
|
::AWS::S3.stub(:new).and_return(s3_mocks)
|
14
14
|
end
|
@@ -28,26 +28,36 @@ describe BackupJenkins::AWS do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe "#
|
32
|
-
it "should get the objects from
|
31
|
+
describe "#files" do
|
32
|
+
it "should get the objects from backup_files_for_this_host and sort them" do
|
33
33
|
a = mock(:key => 1)
|
34
34
|
b = mock(:key => 2)
|
35
35
|
c = mock(:key => 3)
|
36
36
|
|
37
|
-
subject.should_receive(:
|
38
|
-
subject.
|
37
|
+
subject.should_receive(:backup_files_for_this_host).and_return([b, c, a])
|
38
|
+
subject.send(:files).should == [a, b, c]
|
39
39
|
subject.instance_variable_get(:"@files").should == [a, b, c]
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe "#
|
43
|
+
describe "#backup_files_for_this_host" do
|
44
44
|
it "should return the right files" do
|
45
45
|
config.should_receive(:base_file_name).and_return("base_file_name")
|
46
46
|
objects = mock
|
47
47
|
objects.should_receive(:with_prefix).with("base_file_name").and_return([1, 2, 3])
|
48
48
|
subject.should_receive(:s3_files).and_return(objects)
|
49
49
|
|
50
|
-
subject.
|
50
|
+
subject.send(:backup_files_for_this_host).should == [1, 2, 3]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#list_backup_files" do
|
55
|
+
it "should call the right methods" do
|
56
|
+
subject.should_receive(:s3_object_to_hash).twice.and_return(:blah)
|
57
|
+
subject.should_receive(:backup_files_for_all_hosts).and_return([mock, mock])
|
58
|
+
subject.should_receive(:format_backup_file_data).with([:blah, :blah])
|
59
|
+
|
60
|
+
subject.list_backup_files
|
51
61
|
end
|
52
62
|
end
|
53
63
|
|
@@ -56,22 +66,10 @@ describe BackupJenkins::AWS do
|
|
56
66
|
config.stub(:verbose).and_return(false)
|
57
67
|
end
|
58
68
|
|
59
|
-
it "should
|
60
|
-
subject.should_receive(:populate_files)
|
69
|
+
it "should call do_remove_old_files" do
|
61
70
|
subject.should_receive(:do_remove_old_files)
|
62
71
|
subject.remove_old_files
|
63
72
|
end
|
64
|
-
|
65
|
-
it "should print stuff if verbose", :pending => 'failing on JRuby' 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
73
|
end
|
76
74
|
|
77
75
|
describe "#do_remove_old_files" do
|
@@ -85,24 +83,14 @@ describe BackupJenkins::AWS do
|
|
85
83
|
file_2.should_receive(:delete)
|
86
84
|
|
87
85
|
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", :pending => 'failing on JRuby' 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
|
86
|
+
subject.send(:do_remove_old_files)
|
99
87
|
end
|
100
88
|
end
|
101
89
|
|
102
90
|
describe "#files_to_remove" do
|
103
91
|
it "should get the last n files (where n is total number - keep)" do
|
104
92
|
subject.stub(:files).and_return(%w(a b c d e f g))
|
105
|
-
subject.files_to_remove.should == ["a", "b", "c", "d", "e"]
|
93
|
+
subject.send(:files_to_remove).should == ["a", "b", "c", "d", "e"]
|
106
94
|
end
|
107
95
|
end
|
108
96
|
|
@@ -118,19 +106,6 @@ describe BackupJenkins::AWS do
|
|
118
106
|
subject.upload_file("filename", "file")
|
119
107
|
end
|
120
108
|
|
121
|
-
it "should print stuff in verbose", :pending => 'failing on JRuby' 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
109
|
it "should raise exception if no s3 object is created" do
|
135
110
|
config.stub(:verbose).and_return(false)
|
136
111
|
|
@@ -61,6 +61,19 @@ describe BackupJenkins::Backup do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
describe "#list_local_files" do
|
65
|
+
before do
|
66
|
+
config.stub(:backup).and_return("dir_base" => "base")
|
67
|
+
config.stub(:base_file_name).and_return("base_file_name")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should call the right methods" do
|
71
|
+
subject.should_receive(:backup_files)
|
72
|
+
subject.should_receive(:format_backup_file_data)
|
73
|
+
subject.list_local_files
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
64
77
|
describe "#create_dir_and_copy_impl" do
|
65
78
|
before do
|
66
79
|
FileTest.stub(:file?).and_return(true)
|
@@ -19,11 +19,13 @@ describe BackupJenkins::CLI do
|
|
19
19
|
aws.stub(:remove_old_files)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
BackupJenkins::CLI.run
|
22
|
+
describe ".run" do
|
23
|
+
after { BackupJenkins::CLI.run }
|
24
|
+
it { BackupJenkins::CLI.any_instance.should_receive(:run) }
|
24
25
|
end
|
25
26
|
|
26
|
-
describe "
|
27
|
+
describe "#run" do
|
28
|
+
after { subject.run }
|
27
29
|
it { BackupJenkins::AWS.should_receive(:new).with(config) }
|
28
30
|
it { BackupJenkins::Backup.should_receive(:new).with(config) }
|
29
31
|
it { BackupJenkins::Config.should_receive(:new) }
|
@@ -32,4 +34,17 @@ describe BackupJenkins::CLI do
|
|
32
34
|
it { aws.should_receive(:upload_file).with("tarball_filename", :IO) }
|
33
35
|
it { aws.should_receive(:remove_old_files) }
|
34
36
|
end
|
37
|
+
|
38
|
+
describe "#longest_width" do
|
39
|
+
before { subject.stub(:options_possible).and_return([%w(1234), %w(1234567890), %w(123)]) }
|
40
|
+
it { subject.send(:longest_width).should == 10 }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#expand_option" do
|
44
|
+
it {
|
45
|
+
subject.send(:expand_option, ['--this-option', '-t', 0, 'This is my explanation']).should(
|
46
|
+
eq " --this-option, -t This is my explanation"
|
47
|
+
)
|
48
|
+
}
|
49
|
+
end
|
35
50
|
end
|
@@ -39,7 +39,7 @@ describe BackupJenkins::Config do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should print some helpful text if config file doesn't exist" do
|
42
|
-
subject.should_receive(:
|
42
|
+
subject.should_receive(:default_config_file_path).and_return("config")
|
43
43
|
|
44
44
|
YAML.should_receive(:load_file).and_raise(Errno::ENOENT)
|
45
45
|
File.should_receive(:read).and_return("sample")
|
@@ -47,7 +47,7 @@ describe BackupJenkins::Config do
|
|
47
47
|
STDERR.should_receive(:puts).with("Please create a config file in config")
|
48
48
|
STDERR.should_receive(:puts).with("\nIt should look like:\n\nsample")
|
49
49
|
|
50
|
-
expect{ subject.send(:config_file) }.to raise_error SystemExit
|
50
|
+
expect{ subject.send(:config_file, nil) }.to raise_error SystemExit
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class SpecFormatterIncluder
|
4
|
+
include BackupJenkins::Formatter
|
5
|
+
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@config = BackupJenkins::Config.new
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe BackupJenkins::Formatter do
|
14
|
+
subject { SpecFormatterIncluder.new }
|
15
|
+
|
16
|
+
describe "#format_backup_file_data" do
|
17
|
+
let(:files) {
|
18
|
+
[
|
19
|
+
{ :key => "jenkins_berman_20121107_1721.tar.bz2", :content_length => 88762813 },
|
20
|
+
{ :key => "jenkins_berman_20121107_1745.tar.bz2", :content_length => 88762572 },
|
21
|
+
{ :key => "jenkins_berman_20121107_1923.tar.bz2", :content_length => 88761816 },
|
22
|
+
{ :key => "jenkins_berman_20121107_2038.tar.bz2", :content_length => 88752599 },
|
23
|
+
{ :key => "jenkins_cronus_20121107_2033.tar.bz2", :content_length => 17139234 },
|
24
|
+
{ :key => "jenkins_perseo_20121107_0035.tar.bz2", :content_length => 52683965 },
|
25
|
+
{ :key => "jenkins_perseo_20121107_0135.tar.bz2", :content_length => 52684962 }
|
26
|
+
]
|
27
|
+
}
|
28
|
+
|
29
|
+
it "should format things nicely" do
|
30
|
+
output = subject.send(:format_backup_file_data, files)
|
31
|
+
output.should == <<-EOO
|
32
|
+
Berman:
|
33
|
+
- 2012/11/07 17:21 key: jenkins_berman_20121107_1721.tar.bz2 (84.65 MB)
|
34
|
+
- 2012/11/07 17:45 key: jenkins_berman_20121107_1745.tar.bz2 (84.65 MB)
|
35
|
+
- 2012/11/07 19:23 key: jenkins_berman_20121107_1923.tar.bz2 (84.65 MB)
|
36
|
+
- 2012/11/07 20:38 key: jenkins_berman_20121107_2038.tar.bz2 (84.64 MB)
|
37
|
+
|
38
|
+
Cronus:
|
39
|
+
- 2012/11/07 20:33 key: jenkins_cronus_20121107_2033.tar.bz2 (16.35 MB)
|
40
|
+
|
41
|
+
Perseo:
|
42
|
+
- 2012/11/07 00:35 key: jenkins_perseo_20121107_0035.tar.bz2 (50.24 MB)
|
43
|
+
- 2012/11/07 01:35 key: jenkins_perseo_20121107_0135.tar.bz2 (50.24 MB)
|
44
|
+
|
45
|
+
EOO
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#extract_data_from_filename" do
|
50
|
+
it "should obtain important info from filename" do
|
51
|
+
filename = "jenkins_berman_20121107_1721.tar.bz2"
|
52
|
+
|
53
|
+
result = subject.send(:extract_data_from_filename, filename)
|
54
|
+
result.should == [
|
55
|
+
'2012/11/07 17:21',
|
56
|
+
'berman',
|
57
|
+
'jenkins_berman_20121107_1721.tar.bz2'
|
58
|
+
]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
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.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -67,13 +67,15 @@ files:
|
|
67
67
|
- lib/backup_jenkins/backup.rb
|
68
68
|
- lib/backup_jenkins/cli.rb
|
69
69
|
- lib/backup_jenkins/config.rb
|
70
|
+
- lib/backup_jenkins/formatter.rb
|
70
71
|
- lib/backup_jenkins/version.rb
|
71
72
|
- spec/lib/backup_jenkins/aws_spec.rb
|
72
73
|
- spec/lib/backup_jenkins/backup_spec.rb
|
73
74
|
- spec/lib/backup_jenkins/cli_spec.rb
|
74
75
|
- spec/lib/backup_jenkins/config_spec.rb
|
76
|
+
- spec/lib/backup_jenkins/formatter_spec.rb
|
75
77
|
- spec/spec_helper.rb
|
76
|
-
homepage: http://github.com/jcmuller/
|
78
|
+
homepage: http://github.com/jcmuller/backup_jenkins
|
77
79
|
licenses: []
|
78
80
|
post_install_message:
|
79
81
|
rdoc_options: []
|
@@ -87,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
89
|
version: '0'
|
88
90
|
segments:
|
89
91
|
- 0
|
90
|
-
hash:
|
92
|
+
hash: -3794041082511016081
|
91
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
94
|
none: false
|
93
95
|
requirements:
|
@@ -96,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
98
|
version: '0'
|
97
99
|
segments:
|
98
100
|
- 0
|
99
|
-
hash:
|
101
|
+
hash: -3794041082511016081
|
100
102
|
requirements: []
|
101
103
|
rubyforge_project:
|
102
104
|
rubygems_version: 1.8.24
|
@@ -109,3 +111,4 @@ test_files:
|
|
109
111
|
- spec/lib/backup_jenkins/backup_spec.rb
|
110
112
|
- spec/lib/backup_jenkins/cli_spec.rb
|
111
113
|
- spec/lib/backup_jenkins/config_spec.rb
|
114
|
+
- spec/lib/backup_jenkins/formatter_spec.rb
|