rosa-build/app/models/node_instruction.rb

89 lines
2.1 KiB
Ruby
Raw Normal View History

2014-04-14 22:32:25 +01:00
class NodeInstruction < ActiveRecord::Base
STATUSES = [
DISABLED = 'disabled',
READY = 'ready',
RESTARTING = 'restarting',
FAILED = 'failed'
]
2014-04-17 20:08:22 +01:00
LOCK_KEY = 'NodeInstruction::lock-key'
2014-04-14 22:32:25 +01:00
belongs_to :user
scope :duplicate, -> id, user_id {
where.not(id: id.to_i).where(user_id: user_id, status: STATUSES - [DISABLED])
}
2014-04-14 22:32:25 +01:00
attr_encrypted :instruction, key: APP_CONFIG['keys']['node_instruction_secret_key']
validates :user, presence: true
validates :instruction, presence: true, length: { maximum: 10000 }
validates :status, presence: true
validate -> {
errors.add(:status, 'Can be only single active instruction for each node') if !disabled? && NodeInstruction.duplicate(id.to_i, user_id).exists?
2014-04-14 22:32:25 +01:00
}
# attr_accessible :instruction, :user_id, :output, :status
2014-04-14 22:32:25 +01:00
state_machine :status, initial: :ready do
2014-04-15 20:15:52 +01:00
2014-04-17 20:08:22 +01:00
after_transition(on: :restart) do |instruction, transition|
instruction.perform_restart
end
2014-04-15 20:15:52 +01:00
2014-04-14 22:32:25 +01:00
event :ready do
2014-04-15 19:08:43 +01:00
transition %i(ready restarting disabled failed) => :ready
2014-04-14 22:32:25 +01:00
end
event :disable do
transition ready: :disabled
end
event :restart do
2014-04-15 19:08:43 +01:00
transition ready: :restarting
2014-04-14 22:32:25 +01:00
end
2014-04-15 22:26:12 +01:00
event :restart_failed do
2014-04-15 19:08:43 +01:00
transition restarting: :failed
2014-04-14 22:32:25 +01:00
end
end
2014-04-15 20:15:52 +01:00
def perform_restart
2014-04-17 20:08:22 +01:00
restart_failed if NodeInstruction.all_locked?
2014-04-15 20:15:52 +01:00
success = false
2014-04-17 22:55:37 +01:00
stdout = ''
2014-04-15 20:15:52 +01:00
instruction.lines.each do |command|
next if command.blank?
command.chomp!; command.strip!
2014-04-17 22:55:37 +01:00
stdout << %x[ #{command} 2>&1 ]
2014-04-15 20:15:52 +01:00
success = $?.success?
end
build_lists = BuildList.where(builder_id: user_id, external_nodes: [nil, '']).
for_status(BuildList::BUILD_STARTED)
2014-04-15 20:15:52 +01:00
build_lists.find_each do |bl|
bl.update_column(:status, BuildList::BUILD_PENDING)
bl.restart_job
end
2014-04-17 22:55:37 +01:00
update_column(:output, stdout)
2014-04-15 22:26:12 +01:00
success ? ready : restart_failed
2014-04-15 20:15:52 +01:00
end
later :perform_restart, queue: :low
2014-04-17 20:08:22 +01:00
def self.all_locked?
Redis.current.get(LOCK_KEY).present?
end
def self.lock_all
Redis.current.set(LOCK_KEY, 1)
end
def self.unlock_all
Redis.current.del(LOCK_KEY)
end
2014-04-14 22:32:25 +01:00
end