13493: Update CORS OPTIONS test.
[arvados.git] / services / api / lib / salvage_collection.rb
index 9b182cfda350210ac4d42448643f7c38510cdfac..3813f41864d4ac8da3562dd5584ccc8f631bdd13 100755 (executable)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 module SalvageCollection
   # Take two input parameters: a collection uuid and reason
   # Get "src_collection" with the given uuid
@@ -10,38 +14,38 @@ module SalvageCollection
   #   Set portable_data_hash to "d41d8cd98f00b204e9800998ecf8427e+0"
 
   require File.dirname(__FILE__) + '/../config/environment'
-  require 'arvados/keep'
   include ApplicationHelper
   require 'tempfile'
   require 'shellwords'
 
-  def self.salvage_collection_arv_put cmd
+  def salvage_collection_arv_put cmd
     new_manifest = %x(#{cmd})
     if $?.success?
       new_manifest
     else
-      raise "Error during arv-put."
+      raise "Error during arv-put: #{$?} (cmd was #{cmd.inspect})"
     end
   end
 
-  def self.salvage_collection_locator_data manifest
-      # Get all the locators from the original manifest
-      locators = []
-      size = 0
-      manifest.each_line do |line|
-        line.split(' ').each do |word|
-          if match = Keep::Locator::LOCATOR_REGEXP.match(word)
-            word = match[1]+match[2]     # get rid of any hints
-            locators << word
-            size += match[3].to_i
-          end
-        end
+  # Get all the locators (and perhaps other strings that look a lot
+  # like a locators) from the original manifest, even if they don't
+  # appear in the correct positions with the correct space delimiters.
+  def salvage_collection_locator_data manifest
+    locators = []
+    size = 0
+    manifest.scan(/(^|[^[:xdigit:]])([[:xdigit:]]{32})((\+\d+)(\+|\b))?/) do |_, hash, _, sizehint, _|
+      if sizehint
+        locators << hash.downcase + sizehint
+        size += sizehint.to_i
+      else
+        locators << hash.downcase
       end
-      locators << 'd41d8cd98f00b204e9800998ecf8427e+0' if !locators.any?
-      return [locators, size]
+    end
+    locators << 'd41d8cd98f00b204e9800998ecf8427e+0' if !locators.any?
+    return [locators, size]
   end
 
-  def self.salvage_collection uuid, reason='salvaged - see #6277, #6859'
+  def salvage_collection uuid, reason='salvaged - see #6277, #6859'
     act_as_system_user do
       if !ENV['ARVADOS_API_TOKEN'].present? or !ENV['ARVADOS_API_HOST'].present?
         raise "ARVADOS environment variables missing. Please set your admin user credentials as ARVADOS environment variables."
@@ -61,6 +65,7 @@ module SalvageCollection
       # 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
 
       new_manifest = salvage_collection_arv_put "arv-put --as-stream --use-filename invalid_manifest_text.txt #{Shellwords::shellescape(temp_file.path)}"
@@ -75,7 +80,6 @@ module SalvageCollection
       new_collection = Collection.new
       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_collection.manifest_text)
 
       created = new_collection.save!
       raise "New collection creation failed." if !created