2011-11-11 17:13:09 +00:00
|
|
|
class ProductBuildList < ActiveRecord::Base
|
2014-03-11 08:58:36 +00:00
|
|
|
include CommitAndVersion
|
|
|
|
include TimeLiving
|
|
|
|
include FileStoreClean
|
|
|
|
include UrlHelper
|
2014-06-20 19:02:32 +01:00
|
|
|
include AbfWorkerMethods
|
2014-03-11 07:39:25 +00:00
|
|
|
include EventLoggable
|
|
|
|
|
2012-11-07 14:32:46 +00:00
|
|
|
delegate :url_helpers, to: 'Rails.application.routes'
|
2012-11-06 14:13:16 +00:00
|
|
|
|
2013-03-22 18:18:54 +00:00
|
|
|
LIVE_TIME = 2.week # for autostart
|
|
|
|
MAX_LIVE_TIME = 3.month # for manual start;
|
|
|
|
|
2012-12-06 19:18:28 +00:00
|
|
|
BUILD_COMPLETED = 0
|
|
|
|
BUILD_FAILED = 1
|
|
|
|
BUILD_PENDING = 2
|
|
|
|
BUILD_STARTED = 3
|
|
|
|
BUILD_CANCELED = 4
|
|
|
|
BUILD_CANCELING = 5
|
2011-11-11 17:13:09 +00:00
|
|
|
|
2012-03-30 12:26:28 +01:00
|
|
|
STATUSES = [ BUILD_STARTED,
|
|
|
|
BUILD_COMPLETED,
|
2012-11-19 15:11:07 +00:00
|
|
|
BUILD_FAILED,
|
2012-11-19 16:38:08 +00:00
|
|
|
BUILD_PENDING,
|
2012-11-19 15:41:59 +00:00
|
|
|
BUILD_CANCELED,
|
2012-12-07 11:11:12 +00:00
|
|
|
BUILD_CANCELING
|
2013-04-04 12:27:51 +01:00
|
|
|
].freeze
|
2012-03-30 12:26:28 +01:00
|
|
|
|
|
|
|
HUMAN_STATUSES = { BUILD_STARTED => :build_started,
|
|
|
|
BUILD_COMPLETED => :build_completed,
|
2012-11-19 15:11:07 +00:00
|
|
|
BUILD_FAILED => :build_failed,
|
2012-11-19 16:38:08 +00:00
|
|
|
BUILD_PENDING => :build_pending,
|
2012-11-19 15:41:59 +00:00
|
|
|
BUILD_CANCELED => :build_canceled,
|
2012-12-07 11:11:12 +00:00
|
|
|
BUILD_CANCELING => :build_canceling
|
2013-04-04 12:27:51 +01:00
|
|
|
}.freeze
|
2012-03-30 12:26:28 +01:00
|
|
|
|
2014-04-07 22:51:21 +01:00
|
|
|
CACHED_CHROOT_TOKEN_DESCRIPTION = 'cached-chroot'
|
|
|
|
|
2011-11-11 17:13:09 +00:00
|
|
|
belongs_to :product
|
2012-11-06 14:13:16 +00:00
|
|
|
belongs_to :project
|
2012-11-13 14:01:06 +00:00
|
|
|
belongs_to :arch
|
2012-12-14 15:14:33 +00:00
|
|
|
belongs_to :user
|
2012-11-06 14:13:16 +00:00
|
|
|
|
2013-03-07 10:24:33 +00:00
|
|
|
# see: Issue #6
|
2014-03-18 13:58:51 +00:00
|
|
|
before_validation -> { self.arch_id = Arch.find_by(name: 'x86_64').id }, on: :create
|
2013-03-27 14:01:54 +00:00
|
|
|
# field "not_delete" can be changed only if build has been completed
|
2014-03-11 07:39:25 +00:00
|
|
|
before_validation -> { self.not_delete = false unless build_completed?; true }
|
2012-11-12 13:22:19 +00:00
|
|
|
validates :product_id,
|
|
|
|
:status,
|
|
|
|
:project_id,
|
|
|
|
:main_script,
|
2014-01-21 04:51:49 +00:00
|
|
|
:arch_id, presence: true
|
|
|
|
validates :status, inclusion: { in: STATUSES }
|
|
|
|
validates :main_script, :params, length: { maximum: 255 }
|
2011-11-11 17:13:09 +00:00
|
|
|
|
2012-04-03 21:32:57 +01:00
|
|
|
attr_accessor :base_url
|
2012-11-13 09:27:39 +00:00
|
|
|
attr_accessible :status,
|
|
|
|
:base_url,
|
|
|
|
:branch,
|
|
|
|
:project_id,
|
|
|
|
:main_script,
|
|
|
|
:params,
|
|
|
|
:project_version,
|
|
|
|
:commit_hash,
|
2013-03-22 14:06:13 +00:00
|
|
|
:product_id,
|
2013-03-22 18:56:32 +00:00
|
|
|
:not_delete
|
2012-04-03 21:32:57 +01:00
|
|
|
attr_readonly :product_id
|
2012-11-08 21:39:42 +00:00
|
|
|
serialize :results, Array
|
2012-04-03 21:32:57 +01:00
|
|
|
|
|
|
|
|
2014-03-25 20:40:19 +00:00
|
|
|
scope :default_order, -> { order(updated_at: :desc) }
|
2014-03-11 07:39:25 +00:00
|
|
|
scope :for_status, ->(status) { where(status: status) }
|
|
|
|
scope :for_user, ->(user) { where(user_id: user.id) }
|
|
|
|
scope :scoped_to_product_name, ->(product_name) { joins(:product).where('products.name LIKE ?', "%#{product_name}%") }
|
2014-03-20 21:25:43 +00:00
|
|
|
scope :recent, -> { order(updated_at: :desc) }
|
2014-03-11 07:39:25 +00:00
|
|
|
scope :outdated, -> {
|
|
|
|
where(not_delete: false).
|
|
|
|
where("(#{table_name}.created_at < ? AND #{table_name}.autostarted is TRUE) OR #{table_name}.created_at < ?",
|
|
|
|
Time.now - LIVE_TIME, Time.now - MAX_LIVE_TIME)
|
|
|
|
}
|
2011-11-11 17:13:09 +00:00
|
|
|
|
2012-12-07 11:11:12 +00:00
|
|
|
after_create :add_job_to_abf_worker_queue
|
2012-08-06 13:06:42 +01:00
|
|
|
before_destroy :can_destroy?
|
2011-11-11 17:13:09 +00:00
|
|
|
|
2014-01-21 04:51:49 +00:00
|
|
|
state_machine :status, initial: :build_pending do
|
2012-12-06 19:18:28 +00:00
|
|
|
|
|
|
|
event :start_build do
|
2014-01-21 04:51:49 +00:00
|
|
|
transition build_pending: :build_started
|
2012-12-06 19:18:28 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
event :cancel do
|
|
|
|
transition [:build_pending, :build_started] => :build_canceling
|
|
|
|
end
|
2014-01-21 04:51:49 +00:00
|
|
|
after_transition on: :cancel, do: :cancel_job
|
2012-12-06 19:18:28 +00:00
|
|
|
|
2014-01-21 04:51:49 +00:00
|
|
|
# build_canceling: :build_canceled - canceling from UI
|
|
|
|
# build_started: :build_canceled - canceling from worker by time-out (time_living has been expired)
|
2012-12-06 19:18:28 +00:00
|
|
|
event :build_canceled do
|
2012-12-07 09:10:38 +00:00
|
|
|
transition [:build_canceling, :build_started] => :build_canceled
|
2012-12-06 19:18:28 +00:00
|
|
|
end
|
|
|
|
|
2014-01-21 04:51:49 +00:00
|
|
|
# build_canceling: :build_completed - Worker hasn't time to cancel building because build had been already completed
|
2012-12-06 19:18:28 +00:00
|
|
|
event :build_success do
|
2013-02-05 11:44:06 +00:00
|
|
|
transition [:build_started, :build_canceling] => :build_completed
|
2012-12-06 19:18:28 +00:00
|
|
|
end
|
|
|
|
|
2014-01-21 04:51:49 +00:00
|
|
|
# build_canceling: :build_failed - Worker hasn't time to cancel building because build had been already failed
|
2012-12-06 19:18:28 +00:00
|
|
|
event :build_error do
|
2013-02-05 12:05:02 +00:00
|
|
|
transition [:build_started, :build_canceling] => :build_failed
|
2012-12-06 19:18:28 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
HUMAN_STATUSES.each do |code,name|
|
2014-01-21 04:51:49 +00:00
|
|
|
state name, value: code
|
2012-12-06 19:18:28 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-11-09 17:42:25 +00:00
|
|
|
def build_started?
|
|
|
|
status == BUILD_STARTED
|
|
|
|
end
|
|
|
|
|
2012-11-19 15:41:59 +00:00
|
|
|
def build_canceling?
|
|
|
|
status == BUILD_CANCELING
|
|
|
|
end
|
|
|
|
|
2014-04-09 19:44:19 +01:00
|
|
|
def can_destroy?
|
|
|
|
![BUILD_STARTED, BUILD_PENDING, BUILD_CANCELING].include?(status)
|
|
|
|
end
|
|
|
|
|
2012-12-06 14:41:24 +00:00
|
|
|
def can_cancel?
|
2014-04-09 19:44:19 +01:00
|
|
|
[BUILD_STARTED, BUILD_PENDING].include?(status)
|
2012-12-06 14:41:24 +00:00
|
|
|
end
|
|
|
|
|
2011-11-11 17:13:09 +00:00
|
|
|
def event_log_message
|
2014-01-21 04:51:49 +00:00
|
|
|
{product: product.name}.inspect
|
2011-11-11 17:13:09 +00:00
|
|
|
end
|
|
|
|
|
2012-03-30 12:26:28 +01:00
|
|
|
def self.human_status(status)
|
|
|
|
I18n.t("layout.product_build_lists.statuses.#{HUMAN_STATUSES[status]}")
|
|
|
|
end
|
|
|
|
|
|
|
|
def human_status
|
|
|
|
self.class.human_status(status)
|
|
|
|
end
|
|
|
|
|
2012-08-06 13:06:42 +01:00
|
|
|
def can_destroy?
|
2012-11-19 16:38:08 +00:00
|
|
|
[BUILD_COMPLETED, BUILD_FAILED, BUILD_CANCELED].include? status
|
2012-08-06 13:06:42 +01:00
|
|
|
end
|
|
|
|
|
2013-02-14 21:49:18 +00:00
|
|
|
def sha1_of_file_store_files
|
|
|
|
(results || []).map{ |r| r['sha1'] }.compact
|
|
|
|
end
|
|
|
|
|
2011-11-11 17:13:09 +00:00
|
|
|
protected
|
|
|
|
|
2012-12-28 14:00:37 +00:00
|
|
|
def abf_worker_priority
|
2012-12-28 14:09:16 +00:00
|
|
|
''
|
2012-12-28 14:00:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def abf_worker_base_queue
|
|
|
|
'iso_worker'
|
|
|
|
end
|
|
|
|
|
2012-12-06 14:41:24 +00:00
|
|
|
def abf_worker_args
|
2013-02-18 09:10:20 +00:00
|
|
|
file_name = "#{project.name}-#{commit_hash}"
|
2013-09-15 14:18:09 +01:00
|
|
|
opts = default_url_options
|
2014-01-21 04:51:49 +00:00
|
|
|
opts.merge!({user: user.authentication_token, password: ''}) if user.present?
|
2012-11-08 13:04:02 +00:00
|
|
|
srcpath = url_helpers.archive_url(
|
2014-03-18 12:42:46 +00:00
|
|
|
project.name_with_owner,
|
2012-11-08 13:04:02 +00:00
|
|
|
file_name,
|
|
|
|
'tar.gz',
|
2012-12-14 15:41:22 +00:00
|
|
|
opts
|
2012-11-08 13:04:02 +00:00
|
|
|
)
|
2014-04-07 22:51:21 +01:00
|
|
|
|
|
|
|
cmd_params = "BUILD_ID=#{id} "
|
|
|
|
if product.platform.hidden?
|
|
|
|
token = product.platform.tokens.by_active.where(description: CACHED_CHROOT_TOKEN_DESCRIPTION).first
|
|
|
|
cmd_params << "TOKEN=#{token.authentication_token} " if token
|
|
|
|
end
|
|
|
|
cmd_params << params.to_s
|
|
|
|
|
2012-12-06 14:41:24 +00:00
|
|
|
{
|
2014-01-21 04:51:49 +00:00
|
|
|
id: id,
|
2012-11-12 09:41:41 +00:00
|
|
|
# TODO: remove comment
|
2014-01-21 04:51:49 +00:00
|
|
|
# srcpath: 'http://dl.dropbox.com/u/945501/avokhmin-test-iso-script-5d9b463d4e9c06ea8e7c89e1b7ff5cb37e99e27f.tar.gz',
|
2014-04-07 22:51:21 +01:00
|
|
|
srcpath: srcpath,
|
|
|
|
params: cmd_params,
|
|
|
|
time_living: time_living,
|
|
|
|
main_script: main_script,
|
2014-01-21 04:51:49 +00:00
|
|
|
platform: {
|
|
|
|
type: product.platform.distrib_type,
|
|
|
|
name: product.platform.name,
|
|
|
|
arch: arch.name
|
2013-08-12 15:26:57 +01:00
|
|
|
},
|
2014-01-21 04:51:49 +00:00
|
|
|
user: {uname: user.try(:uname), email: user.try(:email)}
|
2012-11-07 14:32:46 +00:00
|
|
|
}
|
2012-12-06 14:41:24 +00:00
|
|
|
end
|
2011-11-11 17:13:09 +00:00
|
|
|
end
|