Skip to content

Commit

Permalink
Merge pull request #4 from AhmedKamal1432/amahi-8
Browse files Browse the repository at this point in the history
multiple bugfixes related to labels, mount points, partition recognition, etc.
  • Loading branch information
cpg committed Aug 8, 2015
2 parents ed298d4 + e55a634 commit ffb0158
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 86 deletions.
10 changes: 0 additions & 10 deletions app/controllers/disk_service_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,4 @@ def operations_progress
message = Device.progress_message(Device.progress)
render json: {percentage: Device.progress, message: message}
end

# Render progress page when click on apply button in 'confirmation' step
# Implicitly send HTTP POST request to process_disk action to start processing the operations
# Expected key:values in @params:
# :debug => Integer value(1) if debug mode has selected in fourth step(confirmation), else nil
def progress
debug_mode = params[:debug]
self.user_selections = {debug: debug_mode}
end

end
13 changes: 13 additions & 0 deletions app/controllers/disk_wizard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,23 @@ def manage_disk
def confirmation
option = params[:option]
label = params[:label].blank? ? nil : params[:label]
if label.size > 11 and user_selections['fs_type'].eql?(3)
redirect_to disk_wizards_engine.manage_path, :flash => {:error => "label have to be less than 12 character in FAT32"}
return false
end
self.user_selections = {option: option, label: label}
@selected_disk = Device.find(user_selections['path'])
end

# Render progress page when click on apply button in 'confirmation' step
# Implicitly send HTTP POST request to process_disk action to start processing the operations
# Expected key:values in @params:
# :debug => Integer value(1) if debug mode has selected in fourth step(confirmation), else nil
def progress
debug_mode = params[:debug]
self.user_selections = {debug: debug_mode}
end

# An AJAX call is made to this action, from process.html.erb to start processing the queue
# Create operation queue according to user selections(user_selections), and enqueue operations
def process_disk
Expand Down
22 changes: 18 additions & 4 deletions app/models/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# inheriting ActiveRecord::Base is not necessary
class Device #< ActiveRecord::Base
include Operation

# 2 Tera byte is the edge between MBR and GPT
GPT_EDGE = 2 * 1024 * 1024 * 1024 * 1024

# Device attributes:
# vendor : Device vendor i.e. Western Digital Technologies
# model : Device model i.e. WDBLWE0120JCH
Expand Down Expand Up @@ -75,17 +79,27 @@ def create_partition(size = nil, type = Partition.PartitionType[:TYPE_PRIMARY])
end

# TODO: Take partition table type as an input parameter , set default to MSDOS
def create_partition_table
DiskUtils.create_partition_table self
def create_partition_table type = 'msdos'
DiskUtils.create_partition_table self, type
end

def format_job params_hash
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Params_hash #{params_hash}"
new_fstype = params_hash[:fs_type]
Device.progress = 10
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Create partition_table #{partition_table}"
#TODO: check the disk size and pass the relevent partition table type (i.e. if device size >= 3TB create GPT table else MSDOS(MBR))
create_partition_table unless partition_table
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:partition_table is '#{partition_table}'"
table = partition_table
if table.eql? "unknown" or table.eql? nil
if self.size.to_i > GPT_EDGE
table_type = 'gpt'
else
table_type = 'msdos'
end
create_partition_table table_type
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Create new partition_table of type #{table_type}"
end

DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Full format label #{params_hash[:label]}"
full_format new_fstype, params_hash[:label]
Device.progress = 40
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
get "get_all_devices" => 'disk_service#get_all_devices'
get "check_label" => 'disk_service#check_label'
get 'debug_info' => 'disk_service#debug_info'
post 'process' => 'disk_service#progress'
post 'process' => 'disk_wizard#progress'
get 'get_progress' => 'disk_service#operations_progress'

match 'select' => 'disk_wizard#select_device',via: [:get,:post]
Expand Down
11 changes: 4 additions & 7 deletions lib/command_executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def initialize command, parameters = nil
# Execute the command with assigned parameters when initializing the object
# == Parameters:
# blocking is true =~ Command.run_now or blocking is not true =~ command.execute
def execute blocking = true, debug = @@debug_mode
def execute debug = @@debug_mode
#If user select debug mode
#1. push current command(command name and parameters) to `operations_log` array, where it will be used to list all the operations took place during the debug mode
#2. Return from the method immediately,to prevent executing further
Expand All @@ -74,15 +74,12 @@ def execute blocking = true, debug = @@debug_mode
check root_folder
script_location = File.join(root_folder, "elevated/")
begin
if blocking
Open3.popen3("sudo", "./dsk-wz.sh", @command, @parameters, :chdir => script_location) do |stdin, stdout, stderr, wait_thr|
@stdout = stdout.read; @stderr = stderr.read; @wait_thr = wait_thr.value
end
else
_, @stdout, @stderr, @wait_thr = Open3.popen3("sudo", "./dsk-wz.sh", @command, @parameters, :chdir => script_location)
Open3.popen3("sudo", "./dsk-wz.sh", @command, @parameters, :chdir => script_location) do |stdin, stdout, stderr, wait_thr|
@stdout = stdout.read; @stderr = stderr.read; @wait_thr = wait_thr.value
end
rescue => error
@success = false
DebugLogger.error "|#{self.class.name}|>|#{__method__}|:failed executing `#{@command}` Error is #{@stderr}"
raise error
end
@exit_status = @wait_thr.exitstatus
Expand Down
86 changes: 61 additions & 25 deletions lib/disk_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class << self
# Return an array of all the attached devices, including hard disks,flash/removable/external devices etc.
# If search is given only search for the given path.
def all_devices search = nil
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Search = #{search}"
partitions = []
devices = []
device = nil
Expand All @@ -29,9 +30,8 @@ def all_devices search = nil
end
lsblk = CommandExecutor.new command, params
lsblk.execute
raise "Command execution error: #{lsblk.stderr.read}" if not lsblk.success?
lsblk.result.each_line.with_index do |line, idx|
next if idx == 0
raise "Command execution error: #{lsblk.stderr}" if not lsblk.success?
lsblk.result.each_line do |line|
data_hash = {}
line.squish!
line_data = line.gsub!(/"(.*?)"/, '\1#').split "#"
Expand Down Expand Up @@ -99,8 +99,8 @@ def partition_type_hex kname
params = " info --query=property --name=#{kname}"
end
udevadm = CommandExecutor.new command, params
udevadm.execute #false, false # None blocking and not debug mode
raise "Command execution error: #{udevadm.stderr.read}" if not udevadm.success?
udevadm.execute false # Not debug mode
raise "Command execution error: #{udevadm.stderr}" if not udevadm.success?
udevadm.result.each_line do |line|
line.squish!
key = 'ID_PART_ENTRY_TYPE'
Expand All @@ -117,8 +117,8 @@ def usage device
end

df = CommandExecutor.new command, params
df.execute #false, false # None blocking and not debug mode
raise "Command execution error: #{df.stderr.read}" if not df.success?
df.execute false # Not debug mode
raise "Command execution error: #{df.stderr}" if not df.success?
line = df.result.lines.pop
line.gsub!(/"/, '')
df_data = line.split(" ")
Expand All @@ -132,7 +132,7 @@ def partition_table device
params = "-sm /dev/#{kname} unit b print free" # Use parted machine parseable output,independent from O/S language -s for --script and -m for --machine
end
parted = CommandExecutor.new command, params
parted.execute #false, false # None blocking and not debug mode
parted.execute false # Not debug mode
return false if not parted.success?

# REFERENCE: http://lists.alioth.debian.org/pipermail/parted-devel/2006-December/000573.html
Expand All @@ -142,6 +142,41 @@ def partition_table device
return table_type
end

def label_partition partition_kname, label
filesystem = get_fs_partition partition_kname
case filesystem
when "ext3", "ext4", "ext2"
command = "e2label"
when "vfat"
# TODO: check prevent user to write label > 11 character in UI
command = "fatlabel"
when "ntfs"
command = "ntfslabel"
else
raise "this partititon filesystem '#{filesystem}' not supported"
end

params = " /dev/#{partition_kname} '#{label}'"
label_pr = CommandExecutor.new command, params
label_pr.execute
raise "Command execution error: Add label = #{label}|message: #{label_pr.stderr}" if not label_pr.success?
end

# Return the filesystem of partition
def get_fs_partition partition_kname
command = "blkid"
params = "-p -o export -u filesystem /dev/#{partition_kname}"
blkid = CommandExecutor.new command, params
blkid.execute
raise "Command execution error: #{blkid.stderr}" if not blkid.success?
blkid.result.each_line do |line|
line.strip!.chomp!
key, value = line.split('=')
return value if key.eql? "TYPE"
end
raise "Cannot find partition file system with this path /dev/#{partition_kname}"
end

def umount device
#un-mounting not guaranteed, remain mounted if device is busy
kname = get_kname device
Expand All @@ -150,7 +185,7 @@ def umount device
umount = CommandExecutor.new command, params
#TODO: This should be a none-blocking call, until unmount the disk/device successfully, can't proceed with other works
umount.execute
raise "Command execution error: #{umount.stderr.read}" if not umount.success?
raise "Command execution error: #{umount.stderr}" if not umount.success?
end

def mount mount_point, disk
Expand All @@ -163,11 +198,11 @@ def mount mount_point, disk

#remount all
command = "mount"
params = "#{disk.path} #{mount_point}"
params = "#{disk.path} '#{mount_point}'"
mount = CommandExecutor.new command, params
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Mount executing"
mount.execute
raise "Command execution error: #{mount.stderr.read}" if not mount.success?
raise "Command execution error: #{mount.stderr}" if not mount.success?
end

def format device, fstype
Expand All @@ -191,7 +226,7 @@ def format device, fstype
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Disk.kname = #{device.kname}, fstype = #{fstype} format params = #{params}"
mkfs = CommandExecutor.new command, params
mkfs.execute
raise "Command execution error: #{mkfs.stderr.read}" if not mkfs.success?
raise "Command execution error: #{mkfs.stderr}" if not mkfs.success?
end

#TODO: Need more testing
Expand All @@ -200,7 +235,7 @@ def create_partition device, partition_type = 'primary', start_unit, end_unit
params = "#{device.path} -s -a optimal unit MB mkpart #{partition_type} ext3 #{start_unit} -- #{end_unit}"
parted = CommandExecutor.new command, params
parted.execute
raise "Command execution error: #{parted.stderr.read}" if not parted.success?
raise "Command execution error: #{parted.stderr}" if not parted.success?
probe_kernal device
end

Expand All @@ -210,7 +245,7 @@ def create_partition_table device, type = 'msdos'
params = "--script #{device.path} mklabel #{type}"
parted = CommandExecutor.new command, params
parted.execute
raise "Command execution error: #{parted.stderr.read}" if not parted.success?
raise "Command execution error: #{parted.stderr}" if not parted.success?
probe_kernal device #inform the OS of partition table changes
end

Expand All @@ -227,7 +262,7 @@ def delete_partition partition
params = "--script #{device_path} rm #{partition.partition_number}"
parted = CommandExecutor.new command, params
parted.execute
raise "Command execution error: #{parted.stderr.read}" if not parted.success?
raise "Command execution error: #{parted.stderr}" if not parted.success?
probe_kernal device_path
end

Expand Down Expand Up @@ -272,7 +307,7 @@ def get_path device
blkid = CommandExecutor.new command, params
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:device = #{device.kname}, uuid = #{device.uuid}, params = #{params}"
blkid.execute
raise "Command execution error:blkid error: #{blkid.stderr.read}" if not blkid.success?
raise "Command execution error:blkid error: #{blkid.stderr}" if not blkid.success?
return blkid.result.lines.first.squish!
end

Expand All @@ -284,8 +319,8 @@ def get_parent child_path
params = " info --query=property --name=#{child_path}"
end
udevadm = CommandExecutor.new command, params
udevadm.execute false, false # None blocking and not debug mode
raise "Command execution error: #{udevadm.stderr.read}" if not udevadm.success?
udevadm.execute false # Not debug mode
raise "Command execution error: #{udevadm.stderr}" if not udevadm.success?
udevadm.result.each_line do |line|
line.squish!
key = 'ID_PART_ENTRY_DISK'
Expand All @@ -299,7 +334,7 @@ def get_parent child_path
end
lsblk = CommandExecutor.new command, params
lsblk.execute
raise "Command execution error: #{lsblk.stderr.read}" if not lsblk.success?
raise "Command execution error: #{lsblk.stderr}" if not lsblk.success?
lsblk.result.each_line do |line|
data_hash = {}
line.squish!
Expand All @@ -321,7 +356,7 @@ def clear_multipath
multipath = CommandExecutor.new command, params
if which command
multipath.execute
raise "Command execution error: #{multipath.stderr}" if not multipath.success?
DebugLogger.error "|#{self.class.name}|>|#{__method__}|: Command execution error: #{multipath.stderr}" unless multipath.success?
else
return false
end
Expand All @@ -333,14 +368,15 @@ def get_partition_number partition_path
params = " info --query=property --name=#{partition_path}"
udevadm = CommandExecutor.new command, params
udevadm.execute
raise "Command execution error: #{udevadm.stderr.read}" if not udevadm.success?
raise "Command execution error: #{udevadm.stderr}" if not udevadm.success?
udevadm.result.each_line do |line|
line.squish!
key = 'ID_PART_ENTRY_NUMBER'
_key, value = line.split '='
return value.to_i if _key.eql? key
end
raise "Can't find partition number for #{partition_path} partition"
DebugLogger.error "Can't find partition number for #{partition_path} partition"
return data_hash['kname'].match(/[0-9]*$/)[0].to_i
end

#Quick `open3` wrapper for check availability of a system command, shows the full path of (shell) commands.Wrapper for linux 'which' command
Expand Down Expand Up @@ -370,10 +406,10 @@ def get_kname device

def create_directory location
command = "mkdir"
params = "-p -m 757 #{location}"
params = "-p -m 757 '#{location}'"
mkdir = CommandExecutor.new command, params
mkdir.execute
raise "Command execution error: #{mkdir.stderr.read}" if not mkdir.success?
raise "Command execution error: #{mkdir.stderr}" if not mkdir.success?
end

def systemctl_wrapper systemd_name, action
Expand All @@ -389,7 +425,7 @@ def systemctl_wrapper systemd_name, action
end
systemctl = CommandExecutor.new command, params
systemctl.execute
raise "Command execution error: #{systemctl.stderr.read}" if not systemctl.success?
raise "Command execution error: #{systemctl.stderr}" if not systemctl.success?
if action == 'show'
_, description = systemctl.result.lines[0].squish!.split('=')
_, active = systemctl.result.lines[1].squish!.split('=')
Expand Down
8 changes: 4 additions & 4 deletions lib/fstab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ def add_entry(opts = {})
params = " #{@contents} ! sudo tee /etc/fstab"
echo = CommandExecutor.new command, params
echo.execute
raise "Command execution error: #{echo.stderr.read}" if not echo.success?
raise "Command execution error: #{echo.stderr}" if not echo.success?
command = "echo"
params = " #{format_entry(dev, opts)} ! sudo tee -a /etc/fstab"
echo = CommandExecutor.new command, params
echo.execute
raise "Command execution error: #{echo.stderr.read}" if not echo.success?
raise "Command execution error: #{echo.stderr}" if not echo.success?
reload
end

Expand Down Expand Up @@ -251,7 +251,7 @@ def self.get_blkdev_fs_attrs(dev)
blkid = CommandExecutor.new command, params
DebugLogger.info "|Fstab|>|#{__method__}|:device = #{dev}"
blkid.execute
raise "Command execution error:blkid error: #{blkid.stderr.read}" if not blkid.success?
raise "Command execution error:blkid error: #{blkid.stderr}" if not blkid.success?
blkid.result.each_line do |line|
line.strip!.chomp!
key, value = line.split('=')
Expand Down Expand Up @@ -322,7 +322,7 @@ def backup_fstab

echo = CommandExecutor.new command, params
echo.execute
raise "Command execution error: #{echo.stderr.read}" if not echo.success?
raise "Command execution error: #{echo.stderr}" if not echo.success?
# File.open("#{@backup_dir}/fstab.#{Time.now.to_f}.bak", 'w') do |f|
# f.puts @contents
# end
Expand Down
Loading

0 comments on commit ffb0158

Please sign in to comment.