From b62ecdbe4e18296af220dbbe4e3d42494c14ef58 Mon Sep 17 00:00:00 2001 From: Mo Morsi Date: Mon, 9 Sep 2013 15:43:52 -0400 Subject: [PATCH] further parameterize disk#create_partition, accept params for % of free space --- lib/linux_admin/disk.rb | 57 ++++++++++++++++++++++++++++++++++++----- spec/disk_spec.rb | 52 ++++++++++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/lib/linux_admin/disk.rb b/lib/linux_admin/disk.rb index 6ade2df..13c9386 100644 --- a/lib/linux_admin/disk.rb +++ b/lib/linux_admin/disk.rb @@ -25,6 +25,30 @@ def str_to_bytes(val, unit) val.to_f.gigabytes end end + + def overlapping_ranges?(ranges) + ranges.find do |range1| + ranges.any? do |range2| + range1 != range2 && + range1.overlaps?(range2) + end + end + end + + def check_if_partitions_overlap(partitions) + ranges = + partitions.collect do |partition| + start = partition[:start] + finish = partition[:end] + start.delete('%') + finish.delete('%') + start.to_f..finish.to_f + end + + if overlapping_ranges?(ranges) + raise ArgumentError, "overlapping partitions" + end + end public @@ -109,27 +133,46 @@ def has_partition_table? result_indicates_partition_table?(result) end - def create_partition(partition_type, size) + def create_partition(partition_type, *args) create_partition_table unless has_partition_table? - id, start = - partitions.empty? ? [1, 0] : - [(partitions.last.id + 1), - partitions.last.end_sector] + start = finish = size = nil + case args.length + when 1 then + start = partitions.empty? ? 0 : partitions.last.end_sector + size = args.first + finish = start + size + + when 2 then + start = args[0] + finish = args[1] + + else + raise ArgumentError, "must specify start/finish or size" + end - options = parted_options_array('mkpart', partition_type, start, start + size) + id = partitions.empty? ? 1 : (partitions.last.id + 1) + options = parted_options_array('mkpart', '-a opt', partition_type, start, finish) run!(cmd(:parted), :params => { nil => options}) partition = Partition.new(:disk => self, :id => id, :start_sector => start, - :end_sector => start+size, + :end_sector => finish, :size => size, :partition_type => partition_type) partitions << partition partition end + def create_partitions(partition_type, *args) + check_if_partitions_overlap(args) + + args.each { |arg| + self.create_partition(partition_type, arg[:start], arg[:end]) + } + end + def clear! @partitions = [] diff --git a/spec/disk_spec.rb b/spec/disk_spec.rb index dd063dc..4908948 100644 --- a/spec/disk_spec.rb +++ b/spec/disk_spec.rb @@ -99,6 +99,35 @@ end end + describe "#create_partitions" do + before(:each) do + @disk = LinuxAdmin::Disk.new(:path => '/dev/hda') + end + + it "dispatches to create_partition" do + @disk.should_receive(:create_partition).with("primary", "0%", "50%") + @disk.create_partitions "primary", :start => "0%", :end => "50%" + end + + context "multiple partitions specified" do + it "calls create_partition for each partition" do + @disk.should_receive(:create_partition).with("primary", "0%", "49%") + @disk.should_receive(:create_partition).with("primary", "50%", "100%") + @disk.create_partitions("primary", {:start => "0%", :end => "49%"}, + {:start => "50%", :end => "100%"}) + end + + context "partitions overlap" do + it "raises argument error" do + expect{ + @disk.create_partitions("primary", {:start => "0%", :end => "50%"}, + {:start => "49%", :end => "100%"}) + }.to raise_error(ArgumentError) + end + end + end + end + describe "#create_partition" do before(:each) do # test disk w/ existing partition @@ -110,12 +139,29 @@ end it "uses parted" do - @disk.should_receive(:run!). - with(@disk.cmd(:parted), - :params => { nil => ['--script', '/dev/hda', 'mkpart', 'primary', 1024, 2048] }) + params = ['--script', '/dev/hda', 'mkpart', '-a opt', 'primary', 1024, 2048] + @disk.should_receive(:run!).with(@disk.cmd(:parted), :params => { nil => params }) @disk.create_partition 'primary', 1024 end + it "accepts start/end params" do + params = ['--script', '/dev/hda', 'mkpart', '-a opt', 'primary', "0%", "50%"] + @disk.should_receive(:run!).with(@disk.cmd(:parted), :params => { nil => params }) + @disk.create_partition 'primary', "0%", "50%" + end + + context "missing params" do + it "raises ArgumentError" do + expect{ + @disk.create_partition 'primary' + }.to raise_error(ArgumentError) + + expect{ + @disk.create_partition 'primary', '0%', '50%', 100 + }.to raise_error(ArgumentError) + end + end + it "returns partition" do @disk.should_receive(:run!) # stub out call to parted partition = @disk.create_partition 'primary', 1024