Merge branch 'master' into 3036-collection-uuids
[arvados.git] / services / api / app / models / job.rb
index dc3539891f30ad325ddb99db524b62f513538eb6..f56b57ac7b42361a216d05f93b07278fea7e1479 100644 (file)
@@ -2,13 +2,14 @@ class Job < ArvadosModel
   include HasUuid
   include KindAndEtag
   include CommonApiTemplate
+  attr_protected :docker_image_locator
   serialize :script_parameters, Hash
   serialize :runtime_constraints, Hash
   serialize :tasks_summary, Hash
   before_create :ensure_unique_submit_id
-  before_create :ensure_script_version_is_commit
-  before_update :ensure_script_version_is_commit
   after_commit :trigger_crunch_dispatch_if_cancelled, :on => :update
+  validate :ensure_script_version_is_commit
+  validate :find_docker_image_locator
 
   has_many :commit_ancestors, :foreign_key => :descendant, :primary_key => :script_version
 
@@ -35,11 +36,12 @@ class Job < ArvadosModel
     t.add :runtime_constraints
     t.add :tasks_summary
     t.add :dependencies
-    t.add :log_stream_href
-    t.add :log_buffer
     t.add :nondeterministic
     t.add :repository
     t.add :supplied_script_version
+    t.add :docker_image_locator
+    t.add :name
+    t.add :description
   end
 
   def assert_finished
@@ -48,12 +50,6 @@ class Job < ArvadosModel
                       running: false)
   end
 
-  def log_stream_href
-    unless self.finished_at
-      "#{current_api_base}/#{self.class.to_s.pluralize.underscore}/#{self.uuid}/log_tail_follow"
-    end
-  end
-
   def self.queue
     self.where('started_at is ? and is_locked_by_uuid is ? and cancelled_at is ? and success is ?',
                nil, nil, nil, nil).
@@ -92,7 +88,8 @@ class Job < ArvadosModel
         self.supplied_script_version = self.script_version if self.supplied_script_version.nil? or self.supplied_script_version.empty?
         self.script_version = sha1
       else
-        raise ArgumentError.new("Specified script_version does not resolve to a commit")
+        self.errors.add :script_version, "#{self.script_version} does not resolve to a commit"
+        return false
       end
     end
   end
@@ -106,6 +103,31 @@ class Job < ArvadosModel
     true
   end
 
+  def find_docker_image_locator
+    # Find the Collection that holds the Docker image specified in the
+    # runtime constraints, and store its locator in docker_image_locator.
+    unless runtime_constraints.is_a? Hash
+      # We're still in validation stage, so we can't assume
+      # runtime_constraints isn't something horrible like an array or
+      # a string. Treat those cases as "no docker image supplied";
+      # other validations will fail anyway.
+      self.docker_image_locator = nil
+      return true
+    end
+    image_search = runtime_constraints['docker_image']
+    image_tag = runtime_constraints['docker_image_tag']
+    if image_search.nil?
+      self.docker_image_locator = nil
+      true
+    elsif coll = Collection.for_latest_docker_image(image_search, image_tag)
+      self.docker_image_locator = coll.portable_data_hash
+      true
+    else
+      errors.add(:docker_image_locator, "not found for #{image_search}")
+      false
+    end
+  end
+
   def dependencies
     deps = {}
     queue = self.script_parameters.values
@@ -171,7 +193,7 @@ class Job < ArvadosModel
       if self.cancelled_at and not self.cancelled_at_was
         self.cancelled_at = Time.now
         self.cancelled_by_user_uuid = current_user.uuid
-        self.cancelled_by_client_uuid = current_api_client.uuid
+        self.cancelled_by_client_uuid = current_api_client.andand.uuid
         @need_crunch_dispatch_trigger = true
       else
         self.cancelled_at = self.cancelled_at_was
@@ -189,15 +211,4 @@ class Job < ArvadosModel
       end
     end
   end
-
-  def log_buffer
-    begin
-      @@redis ||= Redis.new(:timeout => 0)
-      if @@redis.exists uuid
-        @@redis.getrange(uuid, 0 - 2**10, -1)
-      end
-    rescue Redis::CannotConnectError
-      return '(not available)'
-    end
-  end
 end