X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8fc5b6595fd1d544b5812d0807e9747c6eab5f8d..24bcfa0b87b87e4510fffe8a961a5d4a9fd34948:/services/api/app/models/container_request.rb diff --git a/services/api/app/models/container_request.rb b/services/api/app/models/container_request.rb index bf244bd907..a588c86451 100644 --- a/services/api/app/models/container_request.rb +++ b/services/api/app/models/container_request.rb @@ -23,6 +23,7 @@ class ContainerRequest < ArvadosModel api_accessible :user, extend: :common do |t| t.add :command + t.add :container_count t.add :container_count_max t.add :container_image t.add :container_uuid @@ -64,10 +65,24 @@ class ContainerRequest < ArvadosModel %w(modified_by_client_uuid container_uuid requesting_container_uuid) end + # Finalize the container request after the container has + # finished/cancelled. def container_completed! - # may implement retry logic here in the future. - self.state = ContainerRequest::Final - self.save! + update_attributes!(state: ContainerRequest::Final) + c = Container.find_by_uuid(container_uuid) + ['output', 'log'].each do |out_type| + pdh = c.send(out_type) + next if pdh.nil? + manifest = Collection.where(portable_data_hash: pdh).first.manifest_text + Collection.create!(owner_uuid: owner_uuid, + manifest_text: manifest, + portable_data_hash: pdh, + name: "Container #{out_type} for request #{uuid}", + properties: { + 'type' => out_type, + 'container_request' => uuid, + }) + end end protected @@ -78,6 +93,7 @@ class ContainerRequest < ArvadosModel self.runtime_constraints ||= {} self.mounts ||= {} self.cwd ||= "." + self.container_count_max ||= Rails.configuration.container_count_max end # Create a new container (or find an existing one) to satisfy this @@ -87,13 +103,19 @@ class ContainerRequest < ArvadosModel c_runtime_constraints = runtime_constraints_for_container c_container_image = container_image_for_container c = act_as_system_user do - Container.create!(command: self.command, - cwd: self.cwd, - environment: self.environment, - output_path: self.output_path, - container_image: c_container_image, - mounts: c_mounts, - runtime_constraints: c_runtime_constraints) + c_attrs = {command: self.command, + cwd: self.cwd, + environment: self.environment, + output_path: self.output_path, + container_image: c_container_image, + mounts: c_mounts, + runtime_constraints: c_runtime_constraints} + reusable = Container.find_reusable(c_attrs) + if not reusable.nil? + reusable + else + Container.create!(c_attrs) + end end self.container_uuid = c.uuid end @@ -136,7 +158,7 @@ class ContainerRequest < ArvadosModel select(:portable_data_hash). first if !c - raise ActiveRecord::RecordNotFound.new "cannot mount collection #{uuid.inspect}: not found" + raise ArvadosModel::UnresolvableContainerError.new "cannot mount collection #{uuid.inspect}: not found" end if mount['portable_data_hash'].nil? # PDH not supplied by client @@ -154,7 +176,7 @@ class ContainerRequest < ArvadosModel def container_image_for_container coll = Collection.for_latest_docker_image(container_image) if !coll - raise ActiveRecord::RecordNotFound.new "docker image #{container_image.inspect} not found" + raise ArvadosModel::UnresolvableContainerError.new "docker image #{container_image.inspect} not found" end return coll.portable_data_hash end @@ -169,6 +191,14 @@ class ContainerRequest < ArvadosModel if state_changed? and state == Committed and container_uuid.nil? resolve end + if self.container_uuid != self.container_uuid_was + if self.container_count_changed? + errors.add :container_count, "cannot be updated directly." + return false + else + self.container_count += 1 + end + end end def validate_runtime_constraints @@ -206,7 +236,7 @@ class ContainerRequest < ArvadosModel end # Can update priority, container count, name and description - permitted.push :priority, :container_count_max, :container_uuid, :name, :description + permitted.push :priority, :container_count, :container_count_max, :container_uuid, :name, :description if self.state_changed? # Allow create-and-commit in a single operation. @@ -248,7 +278,7 @@ class ContainerRequest < ArvadosModel end def set_requesting_container_uuid - return true if self.requesting_container_uuid # already set + return !new_record? 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