include KindAndEtag
include CommonApiTemplate
- serialize :properties, Hash
serialize :environment, Hash
serialize :mounts, Hash
serialize :runtime_constraints, Hash
serialize :command, Array
- has_many :container_requests, :foreign_key => :container_uuid, :class_name => 'ContainerRequest', :primary_key => :uuid
+ before_validation :fill_field_defaults
+ before_validation :set_timestamps
+ validates :command, :container_image, :output_path, :cwd, :presence => true
+ validate :validate_change
- before_create :set_state_before_save
+ has_many :container_requests, :foreign_key => :container_uuid, :class_name => 'ContainerRequest', :primary_key => :uuid
api_accessible :user, extend: :common do |t|
t.add :command
t.add :runtime_constraints
t.add :started_at
t.add :state
- t.add :uuid
end
# Supported states for a container
(Cancelled = 'Cancelled')
]
- def set_state_before_save
- self.state ||= Queued
+ def fill_field_defaults
+ if self.new_record?
+ self.state ||= Queued
+ self.environment ||= {}
+ self.runtime_constraints ||= {}
+ self.cwd ||= "."
+ end
+ end
+
+ protected
+
+ def permission_to_create
+ current_user.andand.is_admin
+ end
+
+ def permission_to_update
+ current_user.andand.is_admin
+ end
+
+ def check_permitted_updates permitted_fields
+ attribute_names.each do |field|
+ if not permitted_fields.include? field.to_sym and self.send((field.to_s + "_changed?").to_sym)
+ errors.add field, "Illegal update of field #{field}"
+ end
+ end
end
+ def set_timestamps
+ if self.state_changed? and self.state == Running
+ self.started_at ||= db_current_time
+ end
+
+ if self.state_changed? and [Complete, Cancelled].include? self.state
+ self.finished_at ||= db_current_time
+ end
+ end
+
+ def validate_change
+ permitted = [:modified_at, :modified_by_user_uuid, :modified_by_client_uuid]
+
+ if self.new_record?
+ permitted.push :owner_uuid, :command, :container_image, :cwd, :environment,
+ :mounts, :output_path, :priority, :runtime_constraints, :state
+ end
+
+ case self.state
+ when Queued
+ # permit priority change only.
+ if self.state_changed? and not self.state_was.nil?
+ errors.add :state, "Can only go to Queued from nil"
+ else
+ permitted.push :priority
+ end
+ when Running
+ if self.state_changed?
+ if self.state_was == Queued
+ permitted.push :state, :started_at
+ else
+ errors.add :state, "Can only go to Runinng from Queued"
+ end
+ else
+ permitted.push :progress
+ end
+ when Complete, Cancelled
+ if self.state_changed?
+ if self.state_was == Running
+ permitted.push :state, :finished_at, :output, :log
+ elsif self.state_was == Queued
+ permitted.push :state
+ else
+ errors.add :state, "Can only go to #{self.state} from Running"
+ end
+ end
+ else
+ errors.add :state, "Invalid state #{self.state}"
+ end
+
+ check_permitted_updates permitted
+ end
+
+ def validate_fields
+ end
end