diff --git a/lib/linux_admin/disk.rb b/lib/linux_admin/disk.rb index 25b2ac6..69376cb 100644 --- a/lib/linux_admin/disk.rb +++ b/lib/linux_admin/disk.rb @@ -34,21 +34,34 @@ def partitions out.each_line do |l| if l =~ /^ [0-9].*/ p = l.split - id,size,fs_type = p[0], p[3], p[5] - if size =~ /([0-9\.]*)([KMG])B/ - size = case $2 - when 'K' then - $1.to_f.kilobytes - when 'M' then - $1.to_f.megabytes - when 'G' then - $1.to_f.gigabytes - end + args = {:disk => self} + fields = [:id, :start_sector, :end_sector, + :size, :partition_type, :fs_type] + + fields.each_index do |i| + val = p[i] + case fields[i] + when :start_sector, :end_sector, :size + if val =~ /([0-9\.]*)([KMG])B/ + val = case $2 + when 'K' then + $1.to_f.kilobytes + when 'M' then + $1.to_f.megabytes + when 'G' then + $1.to_f.gigabytes + end + end + + when :id + val = val.to_i + + end + + args[fields[i]] = val end - partitions << Partition.new(:disk => self, - :id => id.to_i, - :size => size, - :fs_type => fs_type) + partitions << Partition.new(args) + end end @@ -56,8 +69,24 @@ def partitions end end - def create_partition - # TODO + def create_partition(partition_type, size) + id, start = + partitions.empty? ? [1, 0] : + [(partitions.last.id + 1), + partitions.last.end_sector] + + run(cmd(:parted), + :params => { nil => [path, 'mkpart', partition_type, + start, start + size]}) + + partition = Partition.new(:disk => self, + :id => id, + :start_sector => start, + :end_sector => start+size, + :size => size, + :partition_type => partition_type) + partitions << partition + partition end end end diff --git a/lib/linux_admin/partition.rb b/lib/linux_admin/partition.rb index eafa96b..3b5411b 100644 --- a/lib/linux_admin/partition.rb +++ b/lib/linux_admin/partition.rb @@ -8,7 +8,10 @@ class LinuxAdmin class Partition < LinuxAdmin attr_accessor :id + attr_accessor :partition_type attr_accessor :fs_type + attr_accessor :start_sector + attr_accessor :end_sector attr_accessor :size attr_accessor :disk attr_accessor :mount_point @@ -18,6 +21,9 @@ def initialize(args={}) @size = args[:size] @disk = args[:disk] @fs_type = args[:fs_type] + @start_sector = args[:start_sector] + @end_sector = args[:end_sector] + @partition_type = args[:partition_type] end def path diff --git a/spec/disk_spec.rb b/spec/disk_spec.rb index 3174ce2..4d9ea06 100644 --- a/spec/disk_spec.rb +++ b/spec/disk_spec.rb @@ -49,15 +49,66 @@ disk.partitions[0].id.should == 1 disk.partitions[0].disk.should == disk disk.partitions[0].size.should == 80.5.gigabytes + disk.partitions[0].start_sector.should == 1259.megabytes + disk.partitions[0].end_sector.should == 81.8.gigabytes + disk.partitions[0].partition_type.should == 'primary' disk.partitions[0].fs_type.should == 'ntfs' disk.partitions[1].id.should == 2 disk.partitions[1].disk.should == disk disk.partitions[1].size.should == 80.5.gigabytes + disk.partitions[1].start_sector.should == 81.8.gigabytes + disk.partitions[1].end_sector.should == 162.gigabytes + disk.partitions[1].partition_type.should == 'primary' disk.partitions[1].fs_type.should == 'ext4' disk.partitions[2].id.should == 3 disk.partitions[2].disk.should == disk disk.partitions[2].size.should == 1074.megabytes + disk.partitions[2].start_sector.should == 162.gigabytes + disk.partitions[2].end_sector.should == 163.gigabytes + disk.partitions[2].partition_type.should == 'logical' disk.partitions[2].fs_type.should == 'linux-swap(v1)' end end + + describe "#create_partition" do + before(:each) do + # test disk w/ existing partition + @disk = LinuxAdmin::Disk.new :path => '/dev/hda' + @disk.instance_variable_set(:@partitions, + [LinuxAdmin::Partition.new(:id => 1, + :end_sector => 1024)]) + end + + it "uses parted" do + @disk.should_receive(:run). + with(@disk.cmd(:parted), + :params => { nil => ['/dev/hda', 'mkpart', 'primary', 1024, 2048] }) + @disk.create_partition 'primary', 1024 + end + + it "returns partition" do + @disk.should_receive(:run) # stub out call to parted + partition = @disk.create_partition 'primary', 1024 + partition.should be_an_instance_of(LinuxAdmin::Partition) + end + + it "increments partition id" do + @disk.should_receive(:run) # stub out call to parted + partition = @disk.create_partition 'primary', 1024 + partition.id.should == 2 + end + + it "sets partition start to first unused sector on disk" do + @disk.should_receive(:run) # stub out call to parted + partition = @disk.create_partition 'primary', 1024 + partition.start_sector.should == 1024 + end + + it "stores new partition locally" do + @disk.should_receive(:run) # stub out call to parted + lambda { + @disk.create_partition 'primary', 1024 + }.should change{@disk.partitions.size}.by(1) + end + end end