ebs_snapshot_cleanup 0.5.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 (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
+