So, this one comes up a lot at work, and thanks to knowitnot.com I came accross this example using ruby and fog, its simple, dont runnaway!
Regex lets you define the exact things you want to delete, but be careful. I’m using .* , I’ve removed it and replaced it with some_regex, to make sure people don’t accidentally nuke their cloud files 😀
Install first
yum install rubygem-fog.noarch
#!/usr/bin/env ruby # Author: Jason Barnettrequire 'fog' def delete_file(container, file_num, max_tries) max_retries ||= max_tries try = 0 puts "(#{file_num} of #{container.files.count}) Removing #{container.files[file_num].key}" begin container.files[file_num].destroy rescue Excon::Errors::NotFound, Excon::Errors::Timeout, Fog::Storage::Rackspace::NotFound => e if try == max_retries $stderr.puts e.message else try += 1 puts "Retry \##{try}" retry end end end def equal_div(first, last, num_of_groups) total = last - first group_size = total / num_of_groups + 1 top = first bottom = top + group_size blocks = 1.upto(num_of_groups).inject([]) do |result, x| bottom = last if bottom > last result << [ top, bottom ] top += group_size + 1 bottom = top + group_size result end blocks end service = Fog::Storage.new({ :provider => 'Rackspace', # Rackspace Fog provider :rackspace_username => 'your_rackspace_username', # Your Rackspace Username :rackspace_api_key => 'your_api_key', # Your Rackspace API key :rackspace_region => :ord, # Defaults to :dfw :connection_options => {}, # Optional :rackspace_servicenet => false # Optional, only use if you're the Rackspace Region Data Center }) containers = service.directories.select do |s| s.key =~ /^some_regex/ # Only delete containers that match the regexp end TOT_THREADS = 4 threads = [] containers.each do |container| puts puts "-----------------------------------------" puts "-- Removing _ALL_ objects from #{container.key}" puts "-----------------------------------------" puts #puts "container.files.count: #{container.files.count}" ## separates the number of files into equal groups to distribute to each thread mygroups = equal_div(0, container.files.count - 1, TOT_THREADS) 0.upto(TOT_THREADS - 1) do |thread| threads << Thread.new([ container, mygroups[thread] ]) { |tObject| tObject[1][0].upto(tObject[1][1]) do |x| delete_file(tObject[0], x, 5) end } end threads.each { |aThread| aThread.join } puts "Deleting #{container.key}" container.destroy end
The script works, supporting multiple threads:
(8178 of 10000) Removing conv/2015/04/15/08/bdce78e4cab875e9e17eeeae051b1128.log.gz (3183 of 10000) Removing conv/2015/03/17/18/0ea71bf7a834fc02b01c7f65c4eb23b0.log.gz (5685 of 10000) Removing conv/2015/04/01/08/e4d6a7a2ee83d0be116cca6b1a92ad2a.log.gz (682 of 10000) Removing conv/2015/02/26/07/163f33cf4e33c64139ab3bd7092a9478.log.gz (8179 of 10000) Removing conv/2015/04/15/09/09ef6c4ecaa9341e76648b6e175db888.log.gz (5686 of 10000) Removing conv/2015/04/01/09/23fa1dce145c8343efd8e0227fd41e35.log.gz (3184 of 10000) Removing conv/2015/03/17/18/66cb5ac707c40777a1a78b1486e1c4f3.log.gz (683 of 10000) Removing conv/2015/02/26/07/35f28368ed45b2fb7c7076c3b78eb008.log.gz (5687 of 10000) Removing conv/2015/04/01/09/42882b705c2d7cfe5c726ddec3e457fc.log.gz (3185 of 10000) Removing conv/2015/03/17/18/73dbb421db0093279138b6f69f246c06.log.gz (8180 of 10000) Removing conv/2015/04/15/09/1a01e6b1779b76b5221b1c8c08398b00.log.gz (684 of 10000) Removing conv/2015/02/26/07/44a59e91f6632383f18ff253e4404dba.log.gz (3186 of 10000) Removing conv/2015/03/17/18/8f8ba5791ab0c1979b168517b229ef74.log.gz (5688 of 10000) Removing conv/2015/04/01/09/8ff43c8a5de8a41ee9890686150c8c19.log.gz (8181 of 10000) Removing conv/2015/04/15/09/28035bc7882fe36bb33da670e6c71ac0.log.gz (685 of 10000) Removing conv/2015/02/26/07/7947d1b3f712d175281d33a6073531d9.log.gz (8182 of 10000) Removing conv/2015/04/15/09/34a597377f63709a75c9fd6e8a68e073.log.gz (3187 of 10000) Removing conv/2015/03/17/18/a92a58f166cc9bd1ff54a5f996bb776b.log.gz (5689 of 10000) Removing conv/2015/04/01/09/9a728570208bcac32fd11f1581a57fbb.log.gz