103 lines
2.7 KiB
Ruby
103 lines
2.7 KiB
Ruby
require "json"
|
|
require "base64"
|
|
|
|
module MCollective
|
|
module Agent
|
|
class Erase_node<RPC::Agent
|
|
action "erase_node" do
|
|
erase_node
|
|
end
|
|
|
|
action "reboot_node" do
|
|
reboot
|
|
end
|
|
|
|
private
|
|
|
|
def erase_node
|
|
request_reboot = request.data[:reboot]
|
|
dry_run = request.data[:dry_run]
|
|
error_msg = []
|
|
reply[:status] = 0 # Shell exitcode behaviour
|
|
|
|
begin
|
|
boot_device = get_boot_device
|
|
erase_data(boot_device, 512) unless dry_run
|
|
reply[:erased] = true
|
|
rescue Exception => e
|
|
reply[:erased] = false
|
|
reply[:status] += 1
|
|
msg = "MBR can't be erased. Reason: #{e.message};"
|
|
Log.error(msg)
|
|
error_msg << msg
|
|
end
|
|
|
|
begin
|
|
reboot if not dry_run and request_reboot
|
|
reply[:rebooted] = true
|
|
rescue Exception => e
|
|
reply[:rebooted] = false
|
|
reply[:status] += 1
|
|
msg = "Can't reboot node. Reason: #{e.message};"
|
|
Log.error(msg)
|
|
error_msg << "Can't reboot node. Reason: #{e.message};"
|
|
end
|
|
|
|
unless error_msg.empty?
|
|
reply[:error_msg] = error_msg.join(' ')
|
|
end
|
|
end
|
|
|
|
def get_boot_device
|
|
dev_map = '/boot/grub/device.map'
|
|
grub_conf = '/boot/grub/grub.conf'
|
|
# Look boot device at GRUB device.map file
|
|
if File.file?(dev_map) and File.readable?(dev_map)
|
|
open(dev_map).readlines.each do |l|
|
|
line = l.strip
|
|
unless line.start_with?('#')
|
|
grub_dev, kernel_dev = line.split(%r{[ |\t]+})
|
|
return kernel_dev if grub_dev == '(hd0)'
|
|
end
|
|
end
|
|
end
|
|
# Look boot device at GRUB config autogenerated file
|
|
if File.file?(grub_conf) and File.readable?(grub_conf)
|
|
open(grub_conf).readlines.each do |l|
|
|
line = l.strip
|
|
if line.start_with?('#boot=')
|
|
grub_dev, kernel_dev = line.split('=')
|
|
return kernel_dev
|
|
end
|
|
end
|
|
end
|
|
# If nothing found
|
|
raise 'Boot device not found.'
|
|
end
|
|
|
|
def reboot
|
|
cmd = "/bin/sleep 5; /sbin/shutdown -r now"
|
|
pid = fork { system(cmd) }
|
|
Process.detach(pid)
|
|
end
|
|
|
|
def get_data(file, length, offset=0)
|
|
fd = open(file)
|
|
fd.seek(offset)
|
|
ret = fd.sysread(length)
|
|
fd.close
|
|
return ret
|
|
end
|
|
|
|
def erase_data(file, length, offset=0)
|
|
fd = open(file, 'w')
|
|
fd.seek(offset)
|
|
ret = fd.syswrite("\000"*length)
|
|
fd.close
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
# vi:tabstop=2:expandtab:ai:filetype=ruby
|