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
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 . where ( 'id != ?' , id . to_i ) . where ( user_id : user_id , status : STATUSES - [ DISABLED ] ) . exists?
}
attr_accessible :instruction , :user_id , :output , :status
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
output = ''
instruction . lines . each do | command |
next if command . blank?
command . chomp! ; command . strip!
output << %x[ #{ command } 2>&1 ]
success = $? . success?
end
build_lists = BuildList . where ( builder_id : user_id , external_nodes : [ nil , '' ] ) .
for_status ( BuildList :: BUILD_STARTED )
build_lists . find_each do | bl |
bl . update_column ( :status , BuildList :: BUILD_PENDING )
bl . restart_job
end
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