14873: Fixes unit tests.
[arvados.git] / services / api / app / models / container_request.rb
index cd68517096cbabd40482a99539d91031f4bb91b7..80e1bf3ffe5c7c84bf2251f88b8aa5cb9628404e 100644 (file)
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0
 
 require 'whitelist_update'
+require 'arvados/collection'
 
 class ContainerRequest < ArvadosModel
   include ArvadosModelUpdates
@@ -18,13 +19,13 @@ class ContainerRequest < ArvadosModel
                primary_key: :uuid,
              }
 
-  serialize :properties, Hash
+  # Posgresql JSONB columns should NOT be declared as serialized, Rails 5
+  # already know how to properly treat them.
   serialize :environment, Hash
   serialize :mounts, Hash
   serialize :runtime_constraints, Hash
   serialize :command, Array
   serialize :scheduling_parameters, Hash
-  serialize :secret_mounts, Hash
 
   before_validation :fill_field_defaults, :if => :new_record?
   before_validation :validate_runtime_constraints
@@ -106,8 +107,12 @@ class ContainerRequest < ArvadosModel
   end
 
   def skip_uuid_read_permission_check
-  # XXX temporary until permissions are sorted out.
-    %w(modified_by_client_uuid container_uuid requesting_container_uuid)
+    # The uuid_read_permission_check prevents users from making
+    # references to objects they can't view.  However, in this case we
+    # don't want to do that check since there's a circular dependency
+    # where user can't view the container until the user has
+    # constructed the container request that references the container.
+    %w(container_uuid)
   end
 
   def finalize_if_needed
@@ -150,13 +155,23 @@ class ContainerRequest < ArvadosModel
         coll = Collection.new(
           owner_uuid: self.owner_uuid,
           name: coll_name,
+          manifest_text: "",
           properties: {
             'type' => out_type,
             'container_request' => uuid,
           })
       end
+
+      if out_type == "log"
+        src = Arv::Collection.new(manifest)
+        dst = Arv::Collection.new(coll.manifest_text)
+        dst.cp_r("./", ".", src)
+        dst.cp_r("./", "log for container #{container.uuid}", src)
+        manifest = dst.manifest_text
+      end
+
       coll.assign_attributes(
-        portable_data_hash: pdh,
+        portable_data_hash: Digest::MD5.hexdigest(manifest) + '+' + manifest.bytesize.to_s,
         manifest_text: manifest,
         trash_at: trash_at,
         delete_at: trash_at)
@@ -176,6 +191,7 @@ class ContainerRequest < ArvadosModel
     self.environment ||= {}
     self.runtime_constraints ||= {}
     self.mounts ||= {}
+    self.secret_mounts ||= {}
     self.cwd ||= "."
     self.container_count_max ||= Rails.configuration.container_count_max
     self.scheduling_parameters ||= {}
@@ -199,6 +215,31 @@ class ContainerRequest < ArvadosModel
         return false
       else
         self.container_count += 1
+        if self.container_uuid_was
+          old_container = Container.find_by_uuid(self.container_uuid_was)
+          old_logs = Collection.where(portable_data_hash: old_container.log).first
+          if old_logs
+            log_coll = self.log_uuid.nil? ? nil : Collection.where(uuid: self.log_uuid).first
+            if self.log_uuid.nil?
+              log_coll = Collection.new(
+                owner_uuid: self.owner_uuid,
+                name: coll_name = "Container log for request #{uuid}",
+                manifest_text: "")
+            end
+
+            # copy logs from old container into CR's log collection
+            src = Arv::Collection.new(old_logs.manifest_text)
+            dst = Arv::Collection.new(log_coll.manifest_text)
+            dst.cp_r("./", "log for container #{old_container.uuid}", src)
+            manifest = dst.manifest_text
+
+            log_coll.assign_attributes(
+              portable_data_hash: Digest::MD5.hexdigest(manifest) + '+' + manifest.bytesize.to_s,
+              manifest_text: manifest)
+            log_coll.save_with_unique_name!
+            self.log_uuid = log_coll.uuid
+          end
+        end
       end
     end
   end
@@ -345,7 +386,7 @@ class ContainerRequest < ArvadosModel
   end
 
   def validate_runtime_token
-    if !self.runtime_token.nil?
+    if !self.runtime_token.nil? && self.runtime_token_changed?
       if !runtime_token[0..2] == "v2/"
         errors.add :runtime_token, "not a v2 token"
         return
@@ -388,9 +429,6 @@ class ContainerRequest < ArvadosModel
 
   def get_requesting_container
     return self.requesting_container_uuid if !self.requesting_container_uuid.nil?
-    return if !current_api_client_authorization
-    if (c = Container.where('auth_uuid=?', current_api_client_authorization.uuid).select([:uuid, :priority]).first)
-      return c
-    end
+    Container.for_current_token
   end
 end