X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/0510460e9c5ad8f3d8cf20aa9428115e43284659..71c66323a0ac9ce0cacf3ed3585a07562553096d:/services/api/app/models/collection.rb diff --git a/services/api/app/models/collection.rb b/services/api/app/models/collection.rb index 600c07511b..24e4ccc0ab 100644 --- a/services/api/app/models/collection.rb +++ b/services/api/app/models/collection.rb @@ -1,5 +1,5 @@ class Collection < ArvadosModel - include AssignUuid + include HasUuid include KindAndEtag include CommonApiTemplate @@ -147,4 +147,53 @@ class Collection < ArvadosModel raise "uuid #{uuid} has no hash part" if !hash_part [hash_part, size_part].compact.join '+' end + + def self.uuids_for_docker_image(search_term, search_tag=nil, readers=nil) + readers ||= [Thread.current[:user]] + base_search = Link. + readable_by(*readers). + readable_by(*readers, table_name: "collections"). + joins("JOIN collections ON links.head_uuid = collections.uuid"). + order("links.created_at DESC") + + # If the search term is a Collection locator with an associated + # Docker image hash link, return that Collection. + coll_matches = base_search. + where(link_class: "docker_image_hash", collections: {uuid: search_term}) + if match = coll_matches.first + return [match.head_uuid] + end + + # Find Collections with matching Docker image repository+tag pairs. + matches = base_search. + where(link_class: "docker_image_repo+tag", + name: "#{search_term}:#{search_tag || 'latest'}") + + # If that didn't work, find Collections with matching Docker image hashes. + if matches.empty? + matches = base_search. + where("link_class = ? and name LIKE ?", + "docker_image_hash", "#{search_term}%") + end + + # Generate an order key for each result. We want to order the results + # so that anything with an image timestamp is considered more recent than + # anything without; then we use the link's created_at as a tiebreaker. + uuid_timestamps = {} + matches.find_each do |link| + uuid_timestamps[link.head_uuid] = + [(-link.properties["image_timestamp"].to_datetime.to_i rescue 0), + -link.created_at.to_i] + end + uuid_timestamps.keys.sort_by { |uuid| uuid_timestamps[uuid] } + end + + def self.for_latest_docker_image(search_term, search_tag=nil, readers=nil) + image_uuid = uuids_for_docker_image(search_term, search_tag, readers).last + if image_uuid.nil? + nil + else + find_by_uuid(image_uuid) + end + end end