Merge branch 'master' into origin-8442-cwl-crunch2
[arvados.git] / services / api / app / models / container_request.rb
index acb751c89401424e04d03b950d5acc675dceaca8..496a6b141db2d4f95536430b31edad1f90fba82f 100644 (file)
@@ -18,6 +18,7 @@ class ContainerRequest < ArvadosModel
   validate :validate_state_change
   validate :validate_change
   after_save :update_priority
+  before_create :set_requesting_container_uuid
 
   api_accessible :user, extend: :common do |t|
     t.add :command
@@ -78,32 +79,32 @@ class ContainerRequest < ArvadosModel
     self.cwd ||= "."
   end
 
-  # Turn a container request into a container.
+  # Create a new container (or find an existing one) to satisfy this
+  # request.
   def resolve
-    # In the future this will do things like resolve symbolic git and keep
-    # references to content addresses.
-    Container.create!({ :command => self.command,
-                        :container_image => self.container_image,
-                        :cwd => self.cwd,
-                        :environment => self.environment,
-                        :mounts => self.mounts,
-                        :output_path => self.output_path,
-                        :runtime_constraints => self.runtime_constraints })
+    # TODO: resolve symbolic git and keep references to content
+    # addresses.
+    c = act_as_system_user do
+      Container.create!(command: self.command,
+                        container_image: self.container_image,
+                        cwd: self.cwd,
+                        environment: self.environment,
+                        mounts: self.mounts,
+                        output_path: self.output_path,
+                        runtime_constraints: self.runtime_constraints)
+    end
+    self.container_uuid = c.uuid
   end
 
   def set_container
-    if self.container_uuid_changed?
-      if not current_user.andand.is_admin and not self.container_uuid.nil?
-        errors.add :container_uuid, "can only be updated to nil."
-      end
-    else
-      if self.state_changed?
-        if self.state == Committed and (self.state_was == Uncommitted or self.state_was.nil?)
-          act_as_system_user do
-            self.container_uuid = self.resolve.andand.uuid
-          end
-        end
-      end
+    if (container_uuid_changed? and
+        not current_user.andand.is_admin and
+        not container_uuid.nil?)
+      errors.add :container_uuid, "can only be updated to nil."
+      return false
+    end
+    if state_changed? and state == Committed and container_uuid.nil?
+      resolve
     end
   end
 
@@ -128,8 +129,8 @@ class ContainerRequest < ArvadosModel
         errors.add :priority, "cannot be nil"
       end
 
-      # Can update priority, container count.
-      permitted.push :priority, :container_count_max, :container_uuid
+      # Can update priority, container count, name and description
+      permitted.push :priority, :container_count_max, :container_uuid, :name, :description
 
       if self.state_changed?
         # Allow create-and-commit in a single operation.
@@ -140,12 +141,12 @@ class ContainerRequest < ArvadosModel
       end
 
     when Final
-      if not current_user.andand.is_admin
+      if not current_user.andand.is_admin and not (self.name_changed? || self.description_changed?)
         errors.add :state, "of container request can only be set to Final by system."
       end
 
-      if self.state_changed?
-          permitted.push :state
+      if self.state_changed? || self.name_changed? || self.description_changed?
+          permitted.push :state, :name, :description
       else
         errors.add :state, "does not allow updates"
       end
@@ -158,18 +159,24 @@ class ContainerRequest < ArvadosModel
   end
 
   def update_priority
-    if [Committed, Final].include? self.state and (self.state_changed? or
-                                                   self.priority_changed? or
-                                                   self.container_uuid_changed?)
-      [self.container_uuid_was, self.container_uuid].each do |cuuid|
-        unless cuuid.nil?
-          c = Container.find_by_uuid cuuid
-          act_as_system_user do
-            c.update_priority!
-          end
-        end
+    if self.state_changed? or
+        self.priority_changed? or
+        self.container_uuid_changed?
+      act_as_system_user do
+        Container.
+          where('uuid in (?)',
+                [self.container_uuid_was, self.container_uuid].compact).
+          map(&:update_priority!)
       end
     end
   end
 
+  def set_requesting_container_uuid
+    return true if self.requesting_container_uuid   # already set
+
+    token_uuid = current_api_client_authorization.andand.uuid
+    container = Container.where('auth_uuid=?', token_uuid).order('created_at desc').first
+    self.requesting_container_uuid = container.uuid if container
+    true
+  end
 end