X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/636d833ed4206ffe44e5e9b9b9100ac9d82bc603..f71634c065eff38970b178958349ca9381aee996:/services/api/script/salvage_collection.rb diff --git a/services/api/script/salvage_collection.rb b/services/api/script/salvage_collection.rb index bac033e214..c5f798bd21 100755 --- a/services/api/script/salvage_collection.rb +++ b/services/api/script/salvage_collection.rb @@ -1,4 +1,7 @@ #!/usr/bin/env ruby +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 # Take two input parameters: a collection uuid and reason # Get "src_collection" with the given uuid @@ -10,104 +13,18 @@ # Append to src_collection.name: " (reason; salvaged data at new_collection.uuid)" # Set portable_data_hash to "d41d8cd98f00b204e9800998ecf8427e+0" -require 'trollop' +require 'optimist' +require './lib/salvage_collection' +include SalvageCollection -opts = Trollop::options do +opts = Optimist::options do banner '' banner "Usage: salvage_collection.rb " + "{uuid} {reason}" banner '' - opt :uuid, <<-eos -uuid of the collection to be salvaged. - eos - opt :reason, <<-eos -Reason for salvaging. - eos -end - -if ARGV.count < 1 - Trollop::die "required uuid argument is missing" -end - -uuid, reason = ARGV - -require File.dirname(__FILE__) + '/../config/environment' -require 'arvados/keep' -include ApplicationHelper -require 'tempfile' - -def salvage_collection uuid, reason - act_as_system_user do - src_collection = Collection.find_by_uuid uuid - if !src_collection - $stderr.puts "No collection found for #{uuid}. Returning." - return - end - - begin - src_manifest = src_collection.manifest_text || '' - - # Get all the locators from the original manifest - locators = [] - src_manifest.each_line do |line| - line.split(' ').each do |word| - if match = Keep::Locator::LOCATOR_REGEXP.match(word) - word = word.split('+')[0..1].join('+') # get rid of any hints - locators << word - end - end - end - locators << 'd41d8cd98f00b204e9800998ecf8427e+0' if !locators.any? - - # create new collection using 'arv-put' with original manifest_text as the data - temp_file = Tempfile.new('temp') - temp_file.write(src_manifest) - temp_file.close - - created = %x(arv-put --use-filename invalid_manifest_text.txt #{temp_file.path}) - - temp_file.unlink - - created.rstrip! - match = created.match HasUuid::UUID_REGEX - raise "uuid not found" if !match - - # update this new collection manifest to reference all locators from the original manifest - new_collection = Collection.find_by_uuid created - - new_manifest = new_collection['manifest_text'] - new_manifest = new_manifest.gsub(/\+A[^+]*/, '') - total_size = 0 - locators.each do |locator| - total_size += locator.split('+')[1].to_i - end - new_manifest += (". #{locators.join(' ')} 0:#{total_size}:salvaged_data\n") - - new_collection.name = "salvaged from #{src_collection.uuid}, #{src_collection.portable_data_hash}" - new_collection.manifest_text = new_manifest - new_collection.portable_data_hash = Digest::MD5.hexdigest(new_manifest) - - new_collection.save! - - $stderr.puts "Salvaged manifest and data for #{uuid} are in #{new_collection.uuid}." - puts "Created new collection #{created}" - rescue => error - $stderr.puts "Error creating collection for #{uuid}: #{error}" - return - end - - begin - # update src_collection collection name, pdh, and manifest_text - src_collection.name = (src_collection.name || '') + ' (' + (reason || '') + '; salvaged data at ' + created + ')' - src_collection.manifest_text = '' - src_collection.portable_data_hash = 'd41d8cd98f00b204e9800998ecf8427e+0' - src_collection.save! - $stderr.puts "Collection #{uuid} emptied and renamed to #{src_collection.name.inspect}." - rescue => error - $stderr.puts "Error salvaging collection #{uuid}: #{error}" - end - end + opt :uuid, "uuid of the collection to be salvaged.", type: :string, required: true + opt :reason, "Reason for salvaging.", type: :string, required: false end # Salvage the collection with the given uuid -salvage_collection uuid, reason +SalvageCollection.salvage_collection opts.uuid, opts.reason