ebs_snapshot_cleanup 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.rdoc +22 -0
  2. data/Rakefile +60 -0
  3. data/VERSION +1 -0
  4. data/bin/cleanup-ebs-snapshots +87 -0
  5. metadata +77 -0
@@ -0,0 +1,22 @@
1
+ = ebs_snapshot_cleanup
2
+
3
+ Command-line utility to clean up your EBS snapshots.
4
+
5
+ You'll be prompted before anything is removed. In this version:
6
+
7
+ * every snapshot in the current month is retained
8
+ * last snapshot for every prior month is returned, all others are removed
9
+
10
+ In addition, you're prompted to remove snapshots of volumes that no longer exist.
11
+
12
+ == USAGE
13
+
14
+ Make sure your have an /etc/aws.conf as per aws_credentials[http://github.com/bkoski/aws_credentials]. Then:
15
+
16
+ cleanup-ebs-snapshots
17
+
18
+ and follow the prompts.
19
+
20
+ == AUTHOR
21
+
22
+ Ben Koski, bkoski@nytimes.com
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ebs_snapshot_cleanup"
8
+ gem.summary = %Q{Command-line utility to clean up EBS snapshots}
9
+ gem.description = %Q{Command-line utility to clean up EBS snapshots}
10
+ gem.email = "bkoski@nytimes.com"
11
+ gem.homepage = "http://github.com/bkoski/ebs_snapshot_cleanup"
12
+ gem.authors = ["Ben Koski"]
13
+ gem.add_dependency 'amazon-ec2', '0.9.12'
14
+ gem.add_dependency 'aws_credentials'
15
+ gem.files = ['bin/cleanup-ebs-snapshots','Rakefile','README.rdoc','VERSION']
16
+
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ if File.exist?('VERSION')
51
+ version = File.read('VERSION')
52
+ else
53
+ version = ""
54
+ end
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "ebs_snapshot_cleanup #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.0
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'aws_credentials'
4
+ require 'AWS'
5
+ require 'time'
6
+
7
+ @ec2 = AWS::EC2::Base.new(:access_key_id => AWSCredentials.access_key,
8
+ :secret_access_key => AWSCredentials.secret_access_key)
9
+
10
+
11
+ def get_snapshots_by_volume
12
+ snapshot_data = @ec2.describe_snapshots(:owner => 'self')['snapshotSet']['item']
13
+
14
+ by_volume = {}
15
+ snapshot_data.each do |s|
16
+ by_volume[s['volumeId']] ||= []
17
+ by_volume[s['volumeId']] << s
18
+ end
19
+
20
+ return by_volume
21
+ end
22
+
23
+ active_volume_ids = @ec2.describe_volumes['volumeSet']['item'].collect { |v| v['volumeId'] }
24
+ snapshots_by_volume = get_snapshots_by_volume
25
+
26
+ (snapshots_by_volume.keys - active_volume_ids).each do |orphaned_volume_id|
27
+ next unless snapshots_by_volume.has_key?(orphaned_volume_id)
28
+
29
+ puts
30
+ puts "There are #{snapshots_by_volume[orphaned_volume_id].length} snapshot(s) for #{orphaned_volume_id}, which doesn't appear to exist."
31
+ print "Okay to remove? (y/N) "
32
+
33
+ okay = gets.strip
34
+ if okay.downcase == 'y'
35
+ puts "Removing..."
36
+ snapshots_by_volume[orphaned_volume_id].each { |s| @ec2.delete_snapshot(:snapshot_id => s['snapshotId']) }
37
+ puts "Done!"
38
+ end
39
+ end
40
+
41
+ get_snapshots_by_volume.each do |volume, snapshots|
42
+
43
+ snapshots_by_month = {}
44
+ snaps_to_remove = []
45
+ snapshots.each do |s|
46
+ next if s['status'] != 'completed'
47
+ taken_at = Time.parse(s['startTime'])
48
+
49
+ key = "#{taken_at.year}-#{'%02i' % taken_at.month}"
50
+ snapshots_by_month[key] ||= []
51
+ snapshots_by_month[key] << s
52
+ end
53
+
54
+ snapshots_by_month.each do |month, month_snaps|
55
+ next if month == "#{Time.now.year}-#{'%02i' % Time.now.month}"
56
+ next if month_snaps.length == 1
57
+ snaps_to_remove += month_snaps[0, month_snaps.length - 1]
58
+ end
59
+
60
+ next if snaps_to_remove.length == 0
61
+
62
+ puts
63
+ puts "Volume: #{volume}"
64
+ puts "#{snapshots.length} snapshots total, removing #{snaps_to_remove.length}"
65
+
66
+ puts "Snapshots that will remain:"
67
+ (snapshots - snaps_to_remove).sort { |a,b| a['startTime'] <=> b['startTime'] }.each do |remaining_snap|
68
+ puts "#{remaining_snap['snapshotId']}\t#{remaining_snap['startTime']}"
69
+ end
70
+
71
+ puts
72
+ puts "Snapshots to be removed:"
73
+ snaps_to_remove.sort { |a,b| a['startTime'] <=> b['startTime'] }.each do |snap_to_remove|
74
+ puts "#{snap_to_remove['snapshotId']}\t#{snap_to_remove['startTime']}"
75
+ end
76
+
77
+ puts
78
+ print "Okay to remove #{snaps_to_remove.length} snapshot(s) for volume #{volume}? (y/N) "
79
+ okay = gets.strip
80
+
81
+ if okay.downcase == 'y'
82
+ puts "Removing..."
83
+ snaps_to_remove.each { |s| @ec2.delete_snapshot(:snapshot_id => s['snapshotId']) }
84
+ puts "Done!"
85
+ end
86
+
87
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ebs_snapshot_cleanup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Koski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-05-10 00:00:00 -04:00
13
+ default_executable: cleanup-ebs-snapshots
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: amazon-ec2
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.9.12
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: aws_credentials
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: Command-line utility to clean up EBS snapshots
36
+ email: bkoski@nytimes.com
37
+ executables:
38
+ - cleanup-ebs-snapshots
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - README.rdoc
45
+ - Rakefile
46
+ - VERSION
47
+ - bin/cleanup-ebs-snapshots
48
+ has_rdoc: true
49
+ homepage: http://github.com/bkoski/ebs_snapshot_cleanup
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Command-line utility to clean up EBS snapshots
76
+ test_files: []
77
+