linux_admin 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/linux_admin/common.rb +1 -1
- data/lib/linux_admin/disk.rb +80 -49
- data/lib/linux_admin/fstab.rb +34 -17
- data/lib/linux_admin/logical_volume.rb +5 -16
- data/lib/linux_admin/physical_volume.rb +6 -17
- data/lib/linux_admin/service.rb +11 -4
- data/lib/linux_admin/version.rb +1 -1
- data/lib/linux_admin/volume.rb +33 -0
- data/lib/linux_admin.rb +1 -0
- data/spec/common_spec.rb +5 -0
- data/spec/disk_spec.rb +30 -0
- metadata +3 -2
data/lib/linux_admin/common.rb
CHANGED
data/lib/linux_admin/disk.rb
CHANGED
|
@@ -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 =
|
|
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 ||=
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/lib/linux_admin/fstab.rb
CHANGED
|
@@ -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
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
first_char = line.strip[0]
|
|
43
|
-
|
|
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
|
-
|
|
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 <
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 <
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
data/lib/linux_admin/service.rb
CHANGED
|
@@ -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
|
-
|
|
21
|
-
:params => { nil => ["enable", "#{id}.service"] })
|
|
29
|
+
systemctl 'enable'
|
|
22
30
|
self
|
|
23
31
|
end
|
|
24
32
|
|
|
25
33
|
def disable
|
|
26
|
-
|
|
27
|
-
:params => { nil => ["disable", "#{id}.service"] })
|
|
34
|
+
systemctl 'disable'
|
|
28
35
|
self
|
|
29
36
|
end
|
|
30
37
|
|
data/lib/linux_admin/version.rb
CHANGED
|
@@ -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.
|
|
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-
|
|
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
|