Skip to content

Commit

Permalink
Add probe_kernal method to update part-table changes to kernal,change…
Browse files Browse the repository at this point in the history
… structure of partition,device(previously disk) models(inspired by Gparted)
  • Loading branch information
tmkasun committed Jul 1, 2014
1 parent 42b9d6b commit e309f69
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 24 deletions.
20 changes: 10 additions & 10 deletions app/controllers/disk_wizards_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ def disk_wizard
before_filter :clear_mode, except: [:process_disk]
def select_device
DebugLogger.info "--disk_wizard_start--"
@mounted_disks = Disk.mounts
@new_disks = Disk.new_disks
@mounted_disks = Device.mounts
@new_disks = Device.new_disks
end

def select_fs
Expand All @@ -20,7 +20,7 @@ def select_fs
redirect_to defined?(disk_wizards_engine) ? disk_wizards_engine.select_path : select_path, :flash => { :error => "Please select a device to continue." }
return false
end
@selected_disk = Disk.find(device || user_selections['kname'])
@selected_disk = Device.find(device || user_selections['kname'])
end

def manage_disk
Expand All @@ -38,18 +38,18 @@ def manage_disk
def confirmation
option = params[:option]
self.user_selections = {option: option}
@selected_disk = Disk.find(user_selections['kname'])
@selected_disk = Device.find(user_selections['kname'])
end

def process_disk
kname = user_selections['kname']
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Selected disk/partition = #{kname}"
disk = Disk.find kname
disk = Device.find kname

DiskCommand.debug_mode = !!(self.user_selections['debug'])

jobs_queue = JobQueue.new(user_selections.length)
Disk.progress = 0
Device.progress = 0

if user_selections['format']
para = {kname: kname,fs_type: user_selections['fs_type']}
Expand All @@ -66,10 +66,10 @@ def process_disk
end
result = jobs_queue.process_queue disk
if result == true
Disk.progress = 100
Device.progress = 100
redirect_to(defined?(disk_wizards_engine) ? disk_wizards_engine.complete_path : complete_path)
else
Disk.progress = -1
Device.progress = -1
session[:exception] = result.inspect
redirect_to(defined?(disk_wizards_engine) ? disk_wizards_engine.error_path : error_path)
end
Expand Down Expand Up @@ -105,8 +105,8 @@ def user_selections=(hash)
end

def operations_progress
message = Disk.progress_message(Disk.progress)
render json: {percentage: Disk.progress, message: message}
message = Device.progress_message(Device.progress)
render json: {percentage: Device.progress, message: message}
end

def error
Expand Down
201 changes: 201 additions & 0 deletions app/models/device.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#Since no database involvement in the model, data is fetch on the fly by parsing the result of system calls
# inheriting ActiveRecord::Base is not necessary
class Device #< ActiveRecord::Base

attr_reader :model, :size, :rm
attr_accessor :kname, :partitions

def initialize disk
=begin
std::vector<Partition> partitions ;
Sector length;
Sector heads ;
Sector sectors ;
Sector cylinders ; Number of cylinder
Sector cylsize ;# Cylinder size
Glib::ustring model;
Glib::ustring disktype;
int sector_size ;
bool readonly ;
=end
disk.each do |key, value|
if key.eql? 'partitions' and value
@partitions = []
for partition in value
@partitions.push Partition.new partition
end
next
end
instance_variable_set("@#{key}", value) unless value.nil?
end
end

def self.all
# return array of Disk objects
devices= []
raw_devices = Diskwz.all_devices
for device in raw_devices
device = Device.new device
devices.append device
end
return devices
end

def partition_table
return Diskwz.partition_table self
end

def removable?
return self.rm.eql? 1
end

def self.mounts
return PartitionUtils.new.info
end

def self.new_disks
fstab = Fstab.new
all_devices = Device.all
unmounted_devices = []
for device in all_devices
if device.partitions.blank?
unmounted_devices.push device
next
end
device.partitions.delete_if { |partition| (fstab.has_device? partition.path) }
unmounted_devices.push device if not device.partitions.blank?
end
return unmounted_devices
end

def Device.progress
current_progress = Setting.find_by_kind_and_name('disk_wizard', 'operation_progress')
return 0 unless current_progress
current_progress.value.to_i
end

def path
if @kname =~ /(\/\w+\/).+/
path = @kname
else
path = "/dev/%s" % @kname
end
return path
end

def self.find disk
data_hash = Diskwz.find disk
if data_hash['type'].eql? 'part'
return Partition.new data_hash
else
return Device.new data_hash
end
end

def Device.progress_message(percent)
case percent
when 0 then
"Preparing to partitioning ..."
when 10 then
"Looking for partition table ..."
when 20 then
"Partition table created ..."
when 40 then
"Formating the partition ..."
when 60 then
"Creating mount point ..."
when 80 then
"Mounting the partition ..."
when 100 then
"Disk operations completed."
when -1 then
"Fail (check /var/log/amahi-app-installer.log)."
else
"Unknown status at #{percent}% ."
end
end

# class methods for retrive information about the disks attached to the HDA

def Device.progress=(percentage)
#TODO: if user runs disk_wizard in two browsers concurrently,identifier should set to unique kname of the disk
current_progress = Setting.find_or_create_by('disk_wizard', 'operation_progress', percentage)
if percentage.nil?
current_progress && current_progress.destroy
return nil
end
current_progress.update_attribute(:value, percentage.to_s)
percentage
end

def self.removables
# return an array of removable (Disk objects) device absolute paths
DiskUtils.removables
end

def mount disk
raise "#{__method__} method not implimented !"

end

def unmount
Diskwz.umount self
end

# Delete all excisting partitions and create one partition from entire device/disk
def full_format fstype, label = nil
DebugLogger.info "class = #{self.class.name}, method = #{__method__}"
delete_all_partitions unless partitions.blank?
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Creating partition #{self.kname}"
Diskwz.create_partition self, 1, -1
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Find partition #{@kname}"
new_partition = Device.find @kname + "1"
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Formating #{@kname} to #{fstype}"
new_partition.format fstype
end

#TODO: extend to create new partitions on unallocated spaces
def create_partition size = nil, type = Partition.types[:primary]
new_partition_kname = Diskwz.create_partition self, size[:start_block], size[:end_block]
partitions = Device.find(self).partitions
return partitions.last
end

def create_partition_table
Diskwz.create_partition_table self
end

def format_to filesystem_type
raise "#{__method__} method not implimented !"

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__}|:Full format label #{params_hash['label']}"
full_format new_fstype, params_hash['label']
Device.progress = 40
end

def mount_job params_hash
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Params_hash #{params_hash}"
Device.progress = 60
kname = @kname
label = params_hash['label'] || kname
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:New partition Label #{label}"
new_partition = Device.find kname + "1"
new_partition.mount label
Device.progress = 80
end

def delete_all_partitions
for partition in self.partitions
partition.delete
end
end
end
58 changes: 46 additions & 12 deletions app/models/partition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,50 @@ class Partition
# available: Available free space in the partition in kilobytes(KB)
# type: One of the types in @@types Hash
# kname: Kernal name, name given by linux kernal (i.e. sda1, hda1 etc..)
attr_reader :fstype,:label,:size, :mountpoint, :used, :available, :type
attr_reader :fstype, :label, :size, :mountpoint, :used, :available, :type
attr_accessor :kname

# @@types Globally accessible Hash constant holds the type of partitions which are supported by disk-wizard
# TODO: bit masking can be used to, make the values more machine friendly (i.e. {primary: 0, logical: 1, ....})
@@types = {primary: 'primary', logical: 'logical', extended: 'extended', free: 'free'}
cattr_reader :types
# PartitionType Globally accessible Hash constant holds the type of partitions which are supported by disk-wizard
def self.PartitionType
{
TYPE_PRIMARY: 0,
TYPE_LOGICAL: 1,
TYPE_EXTENDED: 2,
TYPE_UNALLOCATED: 3
}
end

def self.PartitionAlignment
{
ALIGN_CYLINDER: 0, #Align to nearest cylinder
ALIGN_MEBIBYTE: 1, #Align to nearest mebibyte
ALIGN_STRICT: 2 #Strict alignment - no rounding
#Indicator if start and end sectors must remain unchanged
}
end

def self.PartitionStatus
{
STAT_REA: 0,
STAT_NEW: 1,
STAT_COPY: 2,
STAT_FORMATTED: 3
}
end

# partition: Hash value which having keys defined in Partition class attr_*
def initialize partition
partition.each do |key,value|
=begin
#Inpired from Gparted Partition module(https://github.com/GNOME/gparted/blob/master/src/Partition.cc)
this ->partition_number = partition_number;
this ->type = type; #(PartitionType) not available
this ->filesystem = filesystem;
this ->sector_start = sector_start;#currently not available
this ->sector_end = sector_end;#currently not available
this ->sector_size = sector_size;#currently not available
this ->inside_extended = inside_extended;#currently not available
=end
partition.each do |key, value|
instance_variable_set("@#{key}", value) unless value.nil?
end
end
Expand Down Expand Up @@ -71,22 +104,23 @@ def unmount

# Format the partition to given file system type
def format fstype
Diskwz.format self, fstype
unmount if mountpoint
Diskwz.format self, fstype
end

def format_job params_hash
Disk.progress = 10
Device.progress = 10
unmount if mountpoint
new_fstype = params_hash[:fs_type]
format new_fstype
Disk.progress = 40
Device.progress = 40
return true
end

def mount_job params_hash
Disk.progress = 60
Device.progress = 60
mount params_hash['label']
Disk.progress = 80
Device.progress = 80
end

# Number after that signifies the partition on the device(i.e. /dev/sda9 means the ninth partition on the first drive.)
Expand All @@ -104,7 +138,7 @@ def get_disk
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:@Kname = #{@kname}"
disk_kname = @kname.gsub(/[0-9]/, "")
DebugLogger.info "|#{self.class.name}|>|#{__method__}|:Disk_kname = #{disk_kname}"
disk = Disk.find disk_kname
disk = Device.find disk_kname
return disk
end
end
2 changes: 1 addition & 1 deletion app/views/disk_wizards/confirmation.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<br />
<ul class="list-group">
<li class="list-group-item list-group-item-info text-center">
<%= @selected_disk.kind_of?(Disk) ? @selected_disk.model : @selected_disk.disk.model %>
<%= @selected_disk.kind_of?(Device) ? @selected_disk.model : @selected_disk.disk.model %>
</li>
<% if user_selections['format'] %>
<li class="list-group-item text-left">
Expand Down
Loading

0 comments on commit e309f69

Please sign in to comment.