linux_admin 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,7 +46,7 @@ class LinuxAdmin
46
46
  return [] if params.blank?
47
47
  params.collect do |k, v|
48
48
  v = case v
49
- when Array; v.collect(&:shellescape)
49
+ when Array; v.collect {|i| i.to_s.shellescape}
50
50
  when NilClass; v
51
51
  else v.to_s.shellescape
52
52
  end
@@ -7,8 +7,27 @@ require 'linux_admin/partition'
7
7
 
8
8
  class LinuxAdmin
9
9
  class Disk < LinuxAdmin
10
+ PARTED_FIELDS =
11
+ [:id, :start_sector, :end_sector,
12
+ :size, :partition_type, :fs_type]
13
+
10
14
  attr_accessor :path
11
15
 
16
+ private
17
+
18
+ def str_to_bytes(val, unit)
19
+ case unit
20
+ when 'K' then
21
+ val.to_f.kilobytes
22
+ when 'M' then
23
+ val.to_f.megabytes
24
+ when 'G' then
25
+ val.to_f.gigabytes
26
+ end
27
+ end
28
+
29
+ public
30
+
12
31
  def self.local
13
32
  Dir.glob('/dev/[vhs]d[a-z]').collect do |d|
14
33
  Disk.new :path => d
@@ -25,14 +44,7 @@ class LinuxAdmin
25
44
  out = run!(cmd(:fdisk), :params => {"-l" => nil}).output
26
45
  out.each_line { |l|
27
46
  if l =~ /Disk #{path}: ([0-9\.]*) ([KMG])B.*/
28
- size = case $2
29
- when 'K' then
30
- $1.to_f.kilobytes
31
- when 'M' then
32
- $1.to_f.megabytes
33
- when 'G' then
34
- $1.to_f.gigabytes
35
- end
47
+ size = str_to_bytes($1, $2)
36
48
  break
37
49
  end
38
50
  }
@@ -41,54 +53,65 @@ class LinuxAdmin
41
53
  end
42
54
 
43
55
  def partitions
44
- @partitions ||= begin
45
- partitions = []
46
-
47
- # TODO: Should this really catch non-zero RC, set output to the default "" and silently return [] ?
48
- # If so, should other calls to parted also do the same?
49
- # requires sudo
50
- out = run(cmd(:parted),
51
- :params => { nil => [@path, 'print'] }).output
52
-
53
- out.each_line do |l|
54
- if l =~ /^ [0-9].*/
55
- p = l.split
56
- args = {:disk => self}
57
- fields = [:id, :start_sector, :end_sector,
58
- :size, :partition_type, :fs_type]
59
-
60
- fields.each_index do |i|
61
- val = p[i]
62
- case fields[i]
63
- when :start_sector, :end_sector, :size
64
- if val =~ /([0-9\.]*)([KMG])B/
65
- val = case $2
66
- when 'K' then
67
- $1.to_f.kilobytes
68
- when 'M' then
69
- $1.to_f.megabytes
70
- when 'G' then
71
- $1.to_f.gigabytes
72
- end
73
- end
74
-
75
- when :id
76
- val = val.to_i
77
-
78
- end
79
-
80
- args[fields[i]] = val
81
- end
82
- partitions << Partition.new(args)
56
+ @partitions ||=
57
+ parted_output.collect { |disk|
58
+ partition_from_parted(disk)
59
+ }
60
+ end
83
61
 
84
- end
62
+ private
63
+
64
+ def parted_output
65
+ # TODO: Should this really catch non-zero RC, set output to the default "" and silently return [] ?
66
+ # If so, should other calls to parted also do the same?
67
+ # requires sudo
68
+ out = run(cmd(:parted),
69
+ :params => { nil => [@path, 'print'] }).output
70
+ split = []
71
+ out.each_line do |l|
72
+ if l =~ /^ [0-9].*/
73
+ split << l.split
85
74
  end
75
+ end
76
+ split
77
+ end
78
+
79
+
80
+ def partition_from_parted(output_disk)
81
+ args = {:disk => self}
82
+ PARTED_FIELDS.each_index do |i|
83
+ val = output_disk[i]
84
+ case PARTED_FIELDS[i]
85
+ when :start_sector, :end_sector, :size
86
+ if val =~ /([0-9\.]*)([KMG])B/
87
+ val = str_to_bytes($1, $2)
88
+ end
86
89
 
87
- partitions
90
+ when :id
91
+ val = val.to_i
92
+
93
+ end
94
+ args[PARTED_FIELDS[i]] = val
88
95
  end
96
+
97
+ Partition.new(args)
98
+ end
99
+
100
+ public
101
+
102
+ def create_partition_table(type = "msdos")
103
+ run!(cmd(:parted), :params => { nil => [path, "mklabel", type]})
104
+ end
105
+
106
+ def has_partition_table?
107
+ result = run(cmd(:parted), :params => { nil => [path, "print"]})
108
+
109
+ result_indicates_partition_table?(result)
89
110
  end
90
111
 
91
112
  def create_partition(partition_type, size)
113
+ create_partition_table unless has_partition_table?
114
+
92
115
  id, start =
93
116
  partitions.empty? ? [1, 0] :
94
117
  [(partitions.last.id + 1),
@@ -118,5 +141,13 @@ class LinuxAdmin
118
141
 
119
142
  self
120
143
  end
144
+
145
+ private
146
+
147
+ def result_indicates_partition_table?(result)
148
+ # parted exits with 1 but writes this oddly spelled error to stdout.
149
+ missing = (result.exit_status == 1 && result.output.include?("unrecognised disk label"))
150
+ !missing
151
+ end
121
152
  end
122
153
  end
@@ -13,6 +13,26 @@ class LinuxAdmin
13
13
  attr_accessor :mount_options
14
14
  attr_accessor :dumpable
15
15
  attr_accessor :fsck_order
16
+
17
+ def initialize(args = {})
18
+ @device = args[:device]
19
+ @mount_point = args[:mount_point]
20
+ @fs_type = args[:fs_type]
21
+ @mount_options = args[:mount_options]
22
+ @dumpable = args[:dumpable]
23
+ @fsck_order = args[:fsck_order]
24
+ end
25
+
26
+ def self.from_line(fstab_line)
27
+ columns = fstab_line.chomp.split
28
+ FSTabEntry.new :device => columns[0],
29
+ :mount_point => columns[1],
30
+ :fs_type => columns[2],
31
+ :mount_options => columns[3],
32
+ :dumpable => columns[4].to_i,
33
+ :fsck_order => columns[5].to_i
34
+
35
+ end
16
36
  end
17
37
 
18
38
  class FSTab < LinuxAdmin
@@ -35,24 +55,21 @@ class LinuxAdmin
35
55
 
36
56
  private
37
57
 
38
- def refresh
39
- @entries = []
40
- f = File.read('/etc/fstab')
41
- f.each_line { |line|
42
- first_char = line.strip[0]
43
- if first_char != '#' && first_char !~ /\s/
44
- columns = line.split
45
- entry = FSTabEntry.new
46
- entry.device = columns[0]
47
- entry.mount_point = columns[1]
48
- entry.fs_type = columns[2]
49
- entry.mount_options = columns[3]
50
- entry.dumpable = columns[4].to_i
51
- entry.fsck_order = columns[5].to_i
52
- @entries << entry
53
- end
58
+ def read
59
+ contents = File.read('/etc/fstab')
60
+ contents = contents.lines.to_a
61
+ contents.reject! { |line|
62
+ first_char = line.strip[0]
63
+ first_char == '#' || first_char =~ /\s/
54
64
  }
55
- self
65
+ contents
66
+ end
67
+
68
+ def refresh
69
+ @entries =
70
+ read.collect { |line|
71
+ FSTabEntry.from_line line
72
+ }
56
73
  end
57
74
  end
58
75
  end
@@ -4,7 +4,7 @@
4
4
  # Licensed under the MIT License
5
5
 
6
6
  class LinuxAdmin
7
- class LogicalVolume < LinuxAdmin
7
+ class LogicalVolume < Volume
8
8
  # logical volume name
9
9
  attr_accessor :name
10
10
 
@@ -51,22 +51,11 @@ class LinuxAdmin
51
51
 
52
52
  def self.scan
53
53
  @lvs ||= begin
54
- vgs = VolumeGroup.scan
55
- lvs = []
56
-
57
- out = run!(cmd(:lvdisplay), :params => { '-c' => nil}).output
58
-
59
- out.each_line do |line|
60
- fields = line.split(':')
61
- vgname = fields[1]
62
- vg = vgs.find { |vg| vg.name == vgname }
63
-
64
- lvs << LogicalVolume.new(:name => fields[0],
65
- :volume_group => vg,
66
- :sectors => fields[6].to_i)
54
+ scan_volumes(cmd(:lvdisplay)) do |fields, vg|
55
+ LogicalVolume.new(:name => fields[0],
56
+ :volume_group => vg,
57
+ :sectors => fields[6].to_i)
67
58
  end
68
-
69
- lvs
70
59
  end
71
60
  end
72
61
  end
@@ -4,7 +4,7 @@
4
4
  # Licensed under the MIT License
5
5
 
6
6
  class LinuxAdmin
7
- class PhysicalVolume < LinuxAdmin
7
+ class PhysicalVolume < Volume
8
8
  # physical volume device name
9
9
  attr_accessor :device_name
10
10
 
@@ -51,22 +51,11 @@ class LinuxAdmin
51
51
 
52
52
  def self.scan
53
53
  @pvs ||= begin
54
- vgs = VolumeGroup.scan
55
- pvs = []
56
-
57
- out = run!(cmd(:pvdisplay), :params => { '-c' => nil}).output
58
-
59
- out.each_line do |line|
60
- fields = line.split(':')
61
- vgname = fields[1]
62
- vg = vgs.find { |vg| vg.name == vgname}
63
-
64
- pvs << PhysicalVolume.new(:device_name => fields[0],
65
- :volume_group => vg,
66
- :size => fields[2].to_i)
67
- end
68
-
69
- pvs
54
+ scan_volumes(cmd(:pvdisplay)) do |fields, vg|
55
+ PhysicalVolume.new(:device_name => fields[0],
56
+ :volume_group => vg,
57
+ :size => fields[2].to_i)
58
+ end
70
59
  end
71
60
  end
72
61
  end
@@ -7,6 +7,15 @@ class LinuxAdmin
7
7
  class Service < LinuxAdmin
8
8
  attr_accessor :id
9
9
 
10
+ private
11
+
12
+ def systemctl(cmd)
13
+ run!(cmd(:systemctl),
14
+ :params => { nil => [cmd, "#{id}.service"] })
15
+ end
16
+
17
+ public
18
+
10
19
  def initialize(id)
11
20
  @id = id
12
21
  end
@@ -17,14 +26,12 @@ class LinuxAdmin
17
26
  end
18
27
 
19
28
  def enable
20
- run!(cmd(:systemctl),
21
- :params => { nil => ["enable", "#{id}.service"] })
29
+ systemctl 'enable'
22
30
  self
23
31
  end
24
32
 
25
33
  def disable
26
- run!(cmd(:systemctl),
27
- :params => { nil => ["disable", "#{id}.service"] })
34
+ systemctl 'disable'
28
35
  self
29
36
  end
30
37
 
@@ -1,3 +1,3 @@
1
1
  class LinuxAdmin
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -0,0 +1,33 @@
1
+ # LinuxAdmin Logical Volume Representation
2
+ #
3
+ # Copyright (C) 2013 Red Hat Inc.
4
+ # Licensed under the MIT License
5
+
6
+ class LinuxAdmin
7
+ class Volume < LinuxAdmin
8
+ private
9
+
10
+ def self.process_volume_display_line(line)
11
+ groups = VolumeGroup.scan
12
+ fields = line.split(':')
13
+ vgname = fields[1]
14
+ vg = groups.find { |vg| vg.name == vgname }
15
+ return fields, vg
16
+ end
17
+
18
+ protected
19
+
20
+ def self.scan_volumes(cmd)
21
+ volumes = []
22
+
23
+ out = run!(cmd, :params => { '-c' => nil}).output
24
+
25
+ out.each_line do |line|
26
+ fields, vg = process_volume_display_line(line)
27
+ volumes << yield(fields, vg)
28
+ end
29
+
30
+ volumes
31
+ end
32
+ end
33
+ end
data/lib/linux_admin.rb CHANGED
@@ -16,6 +16,7 @@ require 'linux_admin/partition'
16
16
  require 'linux_admin/distro'
17
17
  require 'linux_admin/system'
18
18
  require 'linux_admin/fstab'
19
+ require 'linux_admin/volume'
19
20
  require 'linux_admin/logical_volume'
20
21
  require 'linux_admin/physical_volume'
21
22
  require 'linux_admin/volume_group'
data/spec/common_spec.rb CHANGED
@@ -47,6 +47,11 @@ describe LinuxAdmin::Common do
47
47
  subject.send(run_method, "true", :params => modified_params)
48
48
  end
49
49
 
50
+ it "sanitizes fixnum array params" do
51
+ subject.should_receive(:launch).once.with("true 1", {})
52
+ subject.send(run_method, "true", :params => { nil => [1]})
53
+ end
54
+
50
55
  it "as empty hash" do
51
56
  subject.should_receive(:launch).once.with("true", {})
52
57
  subject.send(run_method, "true", :params => {})
data/spec/disk_spec.rb CHANGED
@@ -106,6 +106,7 @@ eos
106
106
  @disk.instance_variable_set(:@partitions,
107
107
  [LinuxAdmin::Partition.new(:id => 1,
108
108
  :end_sector => 1024)])
109
+ @disk.stub(:has_partition_table? => true)
109
110
  end
110
111
 
111
112
  it "uses parted" do
@@ -139,6 +140,35 @@ eos
139
140
  @disk.create_partition 'primary', 1024
140
141
  }.should change{@disk.partitions.size}.by(1)
141
142
  end
143
+
144
+ it "creates partition table if missing" do
145
+ @disk.stub(:has_partition_table? => false)
146
+ @disk.should_receive(:create_partition_table)
147
+ @disk.should_receive(:run!)
148
+ @disk.create_partition 'primary', 1024
149
+ end
150
+ end
151
+
152
+ describe "#has_partition_table?" do
153
+ it "positive case" do
154
+ disk = LinuxAdmin::Disk.new :path => '/dev/hda'
155
+ disk.should_receive(:run).and_return(double(:output => "", :exit_status => 0))
156
+ disk.should have_partition_table
157
+ end
158
+
159
+ it "negative case" do
160
+ disk = LinuxAdmin::Disk.new :path => '/dev/hda'
161
+ output = "\e[?1034h\r\rError: /dev/sdb: unrecognised disk label\n"
162
+ disk.should_receive(:run).and_return(double(:output => output, :exit_status => 1))
163
+ disk.should_not have_partition_table
164
+ end
165
+ end
166
+
167
+ it "#create_partition_table" do
168
+ disk = LinuxAdmin::Disk.new :path => '/dev/hda'
169
+ options = {:params => {nil => ["/dev/hda", "mklabel", "msdos"]}}
170
+ disk.should_receive(:run!).with(disk.cmd(:parted), options)
171
+ disk.create_partition_table
142
172
  end
143
173
 
144
174
  describe "#clear!" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linux_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-08-16 00:00:00.000000000 Z
15
+ date: 2013-08-22 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
@@ -184,6 +184,7 @@ files:
184
184
  - lib/linux_admin/service.rb
185
185
  - lib/linux_admin/system.rb
186
186
  - lib/linux_admin/version.rb
187
+ - lib/linux_admin/volume.rb
187
188
  - lib/linux_admin/volume_group.rb
188
189
  - lib/linux_admin/yum.rb
189
190
  - linux_admin.gemspec