Skip to content

Commit

Permalink
Added DiskSize operators
Browse files Browse the repository at this point in the history
  • Loading branch information
shundhammer committed Dec 22, 2015
1 parent 13ec093 commit 3d761d9
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 30 deletions.
127 changes: 101 additions & 26 deletions src/lib/storage/storage_disk_size.rb
Expand Up @@ -32,10 +32,14 @@ module Storage
# Class to handle disk sizes in the MB/GB/TB range with readable output.
#
class DiskSize
include Yast::I18n
include Comparable

attr_accessor :size_k

def initialize(size_k=0)
@size_k = size_k
textdomain "storage"
@size_k = size_k.round
end

#
Expand All @@ -48,42 +52,98 @@ def self.kiB(kb_size)
def self.MiB(mb_size)
DiskSize.new(mb_size*1024)
end

def self.GiB(gb_size)
DiskSize.new(gb_size*1024*1024)
DiskSize.new(gb_size*(1024**2))
end

def self.TiB(tb_size)
DiskSize.new(tb_size*1024*1024*1024)
DiskSize.new(tb_size*(1024**3))
end

def to_kiB
@size_k
def self.PiB(tb_size)
DiskSize.new(tb_size*(1024**5))
end

def to_MiB
@size_k/1024.0
def self.EiB(tb_size)
DiskSize.new(tb_size*(1024**6))
end

def to_GiB
@size_k/(1024.0*1024.0)
def self.ZiB(tb_size)
DiskSize.new(tb_size*(1024**7))
end

def to_TiB
@size_k/(1024.0*1024.0*1024.0)
def self.YiB(tb_size)
DiskSize.new(tb_size*(1024**8))
end

def to_s
unit = ["kiB", "MiB", "GiB", "TiB"] # FIXME: translate!

#
# Operators
#

def +(other)
if (other.is_a?(Numeric))
DiskSize.new(@size_k+other)
elsif (other.respond_to?(:size_k))
DiskSize.new(@size_k+other.size_k)
else
raise TypeError, "Numeric value or DiskSize expected"
end
end

def -(other)
if (other.is_a?(Numeric))
DiskSize.new(@size_k-other)
elsif (other.respond_to?(:size_k))
DiskSize.new(@size_k-other.size_k)
else
raise TypeError, "Numeric value or DiskSize expected"
end
end

def *(other)
if (other.is_a?(Numeric))
DiskSize.new(@size_k*other)
else
raise TypeError, "Numeric value expected"
end
end

def /(other)
if (other.is_a?(Numeric))
DiskSize.new(@size_k.to_f/other)
else
raise TypeError, "Numeric value expected"
end
end

# The Comparable mixin will get us operators < > <= >= == != with this
def <=>(other)
if (other.respond_to?(:size_k))
return @size_k <=> other.size_k
else
raise TypeError, "DiskSize expected"
end
end

# Return numeric size and unit ("MiB", "GiB", ...) in human-readable form
# as array: [size, unit]
def to_human_readable
unit = [_("kiB"), _("MiB"), _("GiB"), _("TiB"), _("PiB"), _("EiB"), _("ZiB"), _("YiB")]
unit_index = 0
size = @size_k.to_f

while (size > 1024.0 && unit_index < unit.size-1)
size /= 1024.0
unit_index += 1
end

"#{size} #{unit[unit_index]}"
[size, unit[unit_index]]
end

def to_s
size, unit = to_human_readable
"#{'%.2f' % size} #{unit}"
end
end
end
Expand All @@ -93,19 +153,34 @@ def to_s
if $PROGRAM_NAME == __FILE__ # Called direcly as standalone command? (not via rspec or require)
size = Yast::Storage::DiskSize.new(42)
print "42 kiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.MiB(43)
print "43 MiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.GiB(44)
print "44 GiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.TiB(45)
print "45 TiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.TiB(46*1024)
print "46*1024 TiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.TiB(47*1024*1024*1024*1024*1024)

size = Yast::Storage::DiskSize.PiB(46)
print "46 PiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.EiB(47)
print "47 EiB: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.TiB(48*1024**5)
print "Huge: #{size} (#{size.size_k} kiB)\n"

size = Yast::Storage::DiskSize.MiB(12)*3
print "3*12 MiB: #{size} (#{size.size_k} kiB)\n"

other_size = size+Yast::Storage::DiskSize.MiB(20)
print "3*12+20 MiB: #{other_size} (#{other_size.size_k} kiB)\n"

other_size /= 13
print "(3*12+20)/7 MiB: #{other_size} (#{other_size.size_k} kiB)\n"

print "#{size} < #{other_size} ? -> #{size < other_size}\n"
print "#{size} > #{other_size} ? -> #{size > other_size}\n"
end
142 changes: 138 additions & 4 deletions src/lib/storage/storage_proposal.rb
Expand Up @@ -23,14 +23,18 @@

require "yast"
require "storage"
require "set"
require "pp"

# This file can be invoked separately for minimal testing.
# Use 'sudo' if you do that since it will do hardware probing with libstorage.

module Yast
module Storage
# size constants (base size is kB)
KiB=1
MiB=(1024*KiB)
GiB=(1024*MiB)
TiB=(1024*GiB)
#
# Storage proposal for installation: Class that can suggest how to create
# or change partitions for a Linux system installation based on available
Expand All @@ -40,30 +44,160 @@ class Proposal
include Yast::Logger

# User-configurable settings for the storage proposal.
class Settings
# Those are settings the user can change in the UI.
#
class UserSettings
attr_accessor :use_lvm, :encrypt_volume_group
attr_accessor :root_filesystem_type, :enable_snapshots
attr_accessor :root_filesystem_type, :use_snapshots
attr_accessor :use_separate_home, :home_filesystem_type
attr_accessor :enlarge_swap_for_suspend

def initialize
@use_lvm = false
@encrypt_volume_group = false
@root_filesystem_type = :Btrfs
@enable_snapshots = true
@use_snapshots = true
@use_separate_home = true
@home_filesystem_type = :XFS
@enlarge_swap_for_suspend = false
end
end

# Per-product settings for the storage proposal.
# Those settings are read from /control.xml on the installation media.
# The user can directly override the part inherited from UserSettings.
#
class Settings < UserSettings
attr_accessor :root_base_size
attr_accessor :root_max_size
attr_accessor :root_space_percent
attr_accessor :btrfs_root_size_multiplicator
attr_accessor :limit_try_home
attr_accessor :lvm_keep_unpartitioned_region
attr_accessor :lvm_desired_size
attr_accessor :lvm_home_max_size

def initialize
@root_base_size = 10*GiB
@root_max_size = 40*GiB
@root_space_percent = 50
@btrfs_root_size_multiplicator = 3.0
@limit_try_home = 20*GiB
@lvm_keep_unpartitioned_region = false
@lvm_desired_size = 60*GiB
@lvm_home_max_size = 100*GiB
end

def read_from_xml_file(xml_file_name)
# TO DO
end
end

# Class to represent a planned volume (partition or logical volume) and
# its constraints
#
class Volume
attr_accessor :mount_point
attr_accessor :size, :min_size, :max_size, :desired_size
attr_accessor :can_live_on_logical_volume, :logical_volume_name

def initialize(mount_point)
@mount_point = mount_point
@size = 0
@min_size = 0
@max_size = -1 # -1: unlimited
@desired_size = -1 # -1: unlimited (as large as possible)
@can_live_on_logical_volume = false
@logical_volume_name = nil

if @mount_point != "/boot"
if @mount_point.start_with?("/")
@can_live_on_logical_volume = true
if @mount_point == "/"
@logical_volume_name = "root"
else
@logical_volume_name = @mount_point.sub(%r{^/}, "")
end
end
end
end
end


# Class to provide free space for creating new partitions - either by
# reusing existing unpartitioned space, by deleting existing partitions
# or by resizing an existing Windows partiton.
#
class SpaceMaker
def find_space
end

def make_space
end

def windows_partition?
# TO DO
false
end

def resize_windows_partition
# TO DO
end
end

#
#----------------------------------------------------------------------
#

attr_accessor :settings

def initialize
@settings = Settings.new
@proposal = ""

@root_vol = Volume.new("/")
@home_vol = Volume.new("/home")
@boot_vol = Volume.new("/boot")
@prep_vol = Volume.new("PReP")
@efi_boot_vol = Volume.new("EFI")
# @bios_grub_vol = Volume.new("BIOS_Grub")

@volumes = [ @root_vol, @home_vol, @boot_vol ]
end

# Check if the current setup requires a /boot partition
def boot_partition_needed?
# TO DO
false
end

def add_boot_partition
# TO DO
end

def efi_boot_partition_needed?
# TO DO
false
end

def add_efi_boot_partition
# TO DO
end

def prep_partition_needed?
# TO DO
false
end

def add_prep_partition
# TO DO
end

# Figure out which disk to use
def choose_disk
end

# Create a storage proposal.
def propose
"No disks found - no storage proposal possible"
end
Expand Down

0 comments on commit 3d761d9

Please sign in to comment.