linux_admin 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/linux_admin/common.rb +6 -3
- data/lib/linux_admin/disk.rb +14 -6
- data/lib/linux_admin/distro.rb +1 -1
- data/lib/linux_admin/exceptions.rb +10 -0
- data/lib/linux_admin/fstab.rb +1 -7
- data/lib/linux_admin/logical_volume.rb +27 -3
- data/lib/linux_admin/service.rb +4 -7
- data/lib/linux_admin/version.rb +1 -1
- data/lib/linux_admin/volume.rb +1 -1
- data/lib/linux_admin/volume_group.rb +2 -2
- data/spec/common_spec.rb +25 -3
- data/spec/disk_spec.rb +3 -3
- data/spec/fstab_spec.rb +19 -0
- data/spec/logical_volume_spec.rb +30 -6
- data/spec/physical_volume_spec.rb +2 -2
- data/spec/service_spec.rb +4 -4
- data/spec/volume_group_spec.rb +1 -1
- metadata +2 -2
data/lib/linux_admin/common.rb
CHANGED
@@ -24,7 +24,10 @@ class LinuxAdmin
|
|
24
24
|
error ||= ""
|
25
25
|
self.exitstatus = nil
|
26
26
|
end
|
27
|
-
|
27
|
+
rescue Errno::ENOENT => err
|
28
|
+
raise NoSuchFileError.new(err.message) if NoSuchFileError.detected?(err.message)
|
29
|
+
raise
|
30
|
+
else
|
28
31
|
CommandResult.new(output, error, status)
|
29
32
|
end
|
30
33
|
|
@@ -56,13 +59,13 @@ class LinuxAdmin
|
|
56
59
|
|
57
60
|
def assemble_params(sanitized_params)
|
58
61
|
sanitized_params.collect do |pair|
|
59
|
-
pair_joiner = pair.first.
|
62
|
+
pair_joiner = pair.first.to_s.end_with?("=") ? "" : " "
|
60
63
|
pair.flatten.compact.join(pair_joiner)
|
61
64
|
end.join(" ")
|
62
65
|
end
|
63
66
|
|
64
67
|
def build_cmd(cmd, params = nil)
|
65
|
-
return cmd if params.blank?
|
68
|
+
return cmd.to_s if params.blank?
|
66
69
|
"#{cmd} #{assemble_params(sanitize(params))}"
|
67
70
|
end
|
68
71
|
|
data/lib/linux_admin/disk.rb
CHANGED
@@ -66,7 +66,7 @@ class LinuxAdmin
|
|
66
66
|
# If so, should other calls to parted also do the same?
|
67
67
|
# requires sudo
|
68
68
|
out = run(cmd(:parted),
|
69
|
-
:params => { nil =>
|
69
|
+
:params => { nil => parted_options_array('print') }).output
|
70
70
|
split = []
|
71
71
|
out.each_line do |l|
|
72
72
|
if l =~ /^ [0-9].*/
|
@@ -100,11 +100,11 @@ class LinuxAdmin
|
|
100
100
|
public
|
101
101
|
|
102
102
|
def create_partition_table(type = "msdos")
|
103
|
-
run!(cmd(:parted), :params => { nil =>
|
103
|
+
run!(cmd(:parted), :params => { nil => parted_options_array("mklabel", type)})
|
104
104
|
end
|
105
105
|
|
106
106
|
def has_partition_table?
|
107
|
-
result = run(cmd(:parted), :params => { nil =>
|
107
|
+
result = run(cmd(:parted), :params => { nil => parted_options_array("print")})
|
108
108
|
|
109
109
|
result_indicates_partition_table?(result)
|
110
110
|
end
|
@@ -117,9 +117,8 @@ class LinuxAdmin
|
|
117
117
|
[(partitions.last.id + 1),
|
118
118
|
partitions.last.end_sector]
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
start, start + size]})
|
120
|
+
options = parted_options_array('mkpart', partition_type, start, start + size)
|
121
|
+
run!(cmd(:parted), :params => { nil => options})
|
123
122
|
|
124
123
|
partition = Partition.new(:disk => self,
|
125
124
|
:id => id,
|
@@ -144,6 +143,15 @@ class LinuxAdmin
|
|
144
143
|
|
145
144
|
private
|
146
145
|
|
146
|
+
def parted_options_array(*args)
|
147
|
+
args = args.first if args.first.kind_of?(Array)
|
148
|
+
parted_default_options + args
|
149
|
+
end
|
150
|
+
|
151
|
+
def parted_default_options
|
152
|
+
@parted_default_options ||= ['--script', path].freeze
|
153
|
+
end
|
154
|
+
|
147
155
|
def result_indicates_partition_table?(result)
|
148
156
|
# parted exits with 1 but writes this oddly spelled error to stdout.
|
149
157
|
missing = (result.exit_status == 1 && result.output.include?("unrecognised disk label"))
|
data/lib/linux_admin/distro.rb
CHANGED
@@ -8,6 +8,16 @@ class CommandResultError < StandardError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class LinuxAdmin
|
11
|
+
class NoSuchFileError < Errno::ENOENT
|
12
|
+
def initialize(message)
|
13
|
+
super(message.split("No such file or directory -").last.split(" ").first)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.detected?(message)
|
17
|
+
message.start_with?("No such file or directory -")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
11
21
|
class CredentialError < CommandResultError
|
12
22
|
def initialize(result)
|
13
23
|
super("Invalid username or password", result)
|
data/lib/linux_admin/fstab.rb
CHANGED
@@ -56,13 +56,7 @@ class LinuxAdmin
|
|
56
56
|
private
|
57
57
|
|
58
58
|
def read
|
59
|
-
|
60
|
-
contents = contents.lines.to_a
|
61
|
-
contents.reject! { |line|
|
62
|
-
first_char = line.strip[0]
|
63
|
-
first_char == '#' || first_char =~ /\s/
|
64
|
-
}
|
65
|
-
contents
|
59
|
+
File.read('/etc/fstab').lines.find_all {|line| !line.blank? && !line.strip.starts_with?("#")}
|
66
60
|
end
|
67
61
|
|
68
62
|
def refresh
|
@@ -38,10 +38,34 @@ class LinuxAdmin
|
|
38
38
|
self
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.bytes_to_string(bytes)
|
44
|
+
if bytes > 1.gigabytes
|
45
|
+
(bytes / 1.gigabytes).to_s + "G"
|
46
|
+
elsif bytes > 1.megabytes
|
47
|
+
(bytes / 1.megabytes).to_s + "M"
|
48
|
+
elsif bytes > 1.kilobytes
|
49
|
+
(bytes / 1.kilobytes).to_s + "K"
|
50
|
+
else
|
51
|
+
bytes.to_s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
public
|
56
|
+
|
57
|
+
def self.create(name, vg, value)
|
42
58
|
self.scan # initialize local logical volumes
|
43
|
-
|
44
|
-
|
59
|
+
params = { '-n' => name, nil => vg.name}
|
60
|
+
size = nil
|
61
|
+
if value <= 100
|
62
|
+
# size = # TODO size from extents
|
63
|
+
params.merge!({'-l' => "#{value}%FREE"})
|
64
|
+
else
|
65
|
+
size = value
|
66
|
+
params.merge!({'-L' => bytes_to_string(size)})
|
67
|
+
end
|
68
|
+
run!(cmd(:lvcreate), :params => params)
|
45
69
|
lv = LogicalVolume.new :name => name,
|
46
70
|
:volume_group => vg,
|
47
71
|
:sectors => size
|
data/lib/linux_admin/service.rb
CHANGED
@@ -9,11 +9,6 @@ class LinuxAdmin
|
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
|
-
def systemctl(cmd)
|
13
|
-
run!(cmd(:systemctl),
|
14
|
-
:params => { nil => [cmd, "#{id}.service"] })
|
15
|
-
end
|
16
|
-
|
17
12
|
public
|
18
13
|
|
19
14
|
def initialize(id)
|
@@ -26,12 +21,14 @@ class LinuxAdmin
|
|
26
21
|
end
|
27
22
|
|
28
23
|
def enable
|
29
|
-
|
24
|
+
run!(cmd(:chkconfig),
|
25
|
+
:params => { nil => [id, "on"] })
|
30
26
|
self
|
31
27
|
end
|
32
28
|
|
33
29
|
def disable
|
34
|
-
|
30
|
+
run!(cmd(:chkconfig),
|
31
|
+
:params => { nil => [id, "off"] })
|
35
32
|
self
|
36
33
|
end
|
37
34
|
|
data/lib/linux_admin/version.rb
CHANGED
data/lib/linux_admin/volume.rb
CHANGED
@@ -60,8 +60,8 @@ class LinuxAdmin
|
|
60
60
|
out = run!(cmd(:vgdisplay), :params => { '-c' => nil}).output
|
61
61
|
|
62
62
|
out.each_line do |line|
|
63
|
-
fields = line.split(':')
|
64
|
-
vgs << VolumeGroup.new(:name
|
63
|
+
fields = line.lstrip.split(':')
|
64
|
+
vgs << VolumeGroup.new(:name => fields[0])
|
65
65
|
end
|
66
66
|
|
67
67
|
vgs
|
data/spec/common_spec.rb
CHANGED
@@ -37,7 +37,7 @@ describe LinuxAdmin::Common do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
shared_examples_for "run" do
|
40
|
-
context "
|
40
|
+
context "paramater and command handling" do
|
41
41
|
before do
|
42
42
|
subject.stub(:exitstatus => 0)
|
43
43
|
end
|
@@ -49,7 +49,19 @@ describe LinuxAdmin::Common do
|
|
49
49
|
|
50
50
|
it "sanitizes fixnum array params" do
|
51
51
|
subject.should_receive(:launch).once.with("true 1", {})
|
52
|
-
subject.send(run_method, "true", :params => {
|
52
|
+
subject.send(run_method, "true", :params => {nil => [1]})
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sanitizes Pathname option value" do
|
56
|
+
require 'pathname'
|
57
|
+
subject.should_receive(:launch).once.with("true /usr/bin/ruby", {})
|
58
|
+
subject.send(run_method, "true", :params => {nil => [Pathname.new("/usr/bin/ruby")]})
|
59
|
+
end
|
60
|
+
|
61
|
+
it "sanitizes Pathname option" do
|
62
|
+
require 'pathname'
|
63
|
+
subject.should_receive(:launch).once.with("true /usr/bin/ruby", {})
|
64
|
+
subject.send(run_method, "true", :params => {Pathname.new("/usr/bin/ruby") => nil})
|
53
65
|
end
|
54
66
|
|
55
67
|
it "as empty hash" do
|
@@ -69,6 +81,16 @@ describe LinuxAdmin::Common do
|
|
69
81
|
expect(orig_params).to eq(params)
|
70
82
|
end
|
71
83
|
|
84
|
+
it "Pathname command" do
|
85
|
+
subject.should_receive(:launch).once.with("/usr/bin/ruby", {})
|
86
|
+
subject.send(run_method, Pathname.new("/usr/bin/ruby"), {})
|
87
|
+
end
|
88
|
+
|
89
|
+
it "Pathname command with params" do
|
90
|
+
subject.should_receive(:launch).once.with("/usr/bin/ruby -v", {})
|
91
|
+
subject.send(run_method, Pathname.new("/usr/bin/ruby"), :params => {"-v" => nil})
|
92
|
+
end
|
93
|
+
|
72
94
|
it "supports spawn's chdir option" do
|
73
95
|
subject.should_receive(:launch).once.with("true", {:chdir => ".."})
|
74
96
|
subject.send(run_method, "true", :chdir => "..")
|
@@ -100,7 +122,7 @@ describe LinuxAdmin::Common do
|
|
100
122
|
end
|
101
123
|
|
102
124
|
it "command bad" do
|
103
|
-
expect {subject.send(run_method, "XXXXX")}.to raise_error(
|
125
|
+
expect {subject.send(run_method, "XXXXX --user=bob")}.to raise_error(LinuxAdmin::NoSuchFileError, "No such file or directory - XXXXX")
|
104
126
|
end
|
105
127
|
|
106
128
|
context "#exit_status" do
|
data/spec/disk_spec.rb
CHANGED
@@ -48,7 +48,7 @@ eos
|
|
48
48
|
disk = LinuxAdmin::Disk.new :path => '/dev/hda'
|
49
49
|
disk.should_receive(:run).
|
50
50
|
with(disk.cmd(:parted),
|
51
|
-
:params => { nil =>
|
51
|
+
:params => { nil => %w(--script /dev/hda print) }).and_return(double(:output => ""))
|
52
52
|
disk.partitions
|
53
53
|
end
|
54
54
|
|
@@ -112,7 +112,7 @@ eos
|
|
112
112
|
it "uses parted" do
|
113
113
|
@disk.should_receive(:run!).
|
114
114
|
with(@disk.cmd(:parted),
|
115
|
-
:params => { nil => ['/dev/hda', 'mkpart', 'primary', 1024, 2048] })
|
115
|
+
:params => { nil => ['--script', '/dev/hda', 'mkpart', 'primary', 1024, 2048] })
|
116
116
|
@disk.create_partition 'primary', 1024
|
117
117
|
end
|
118
118
|
|
@@ -166,7 +166,7 @@ eos
|
|
166
166
|
|
167
167
|
it "#create_partition_table" do
|
168
168
|
disk = LinuxAdmin::Disk.new :path => '/dev/hda'
|
169
|
-
options = {:params => {nil =>
|
169
|
+
options = {:params => {nil => %w(--script /dev/hda mklabel msdos)}}
|
170
170
|
disk.should_receive(:run!).with(disk.cmd(:parted), options)
|
171
171
|
disk.create_partition_table
|
172
172
|
end
|
data/spec/fstab_spec.rb
CHANGED
@@ -2,8 +2,26 @@ require 'spec_helper'
|
|
2
2
|
require 'stringio'
|
3
3
|
|
4
4
|
describe LinuxAdmin::FSTab do
|
5
|
+
before do
|
6
|
+
# Reset the singleton so subsequent tests get a new instance
|
7
|
+
Singleton.send :__init__, LinuxAdmin::FSTab
|
8
|
+
end
|
9
|
+
|
10
|
+
it "newline, single spaces, tab" do
|
11
|
+
fstab = <<eos
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
eos
|
16
|
+
File.should_receive(:read).with('/etc/fstab').and_return(fstab)
|
17
|
+
LinuxAdmin::FSTab.instance.entries.size.should == 0
|
18
|
+
end
|
19
|
+
|
5
20
|
it "creates FSTabEntry for each line in fstab" do
|
6
21
|
fstab = <<eos
|
22
|
+
# Comment, indented comment, comment with device information
|
23
|
+
# /dev/sda1 / ext4 defaults 1 1
|
24
|
+
# /dev/sda1 / ext4 defaults 1 1
|
7
25
|
/dev/sda1 / ext4 defaults 1 1
|
8
26
|
/dev/sda2 swap swap defaults 0 0
|
9
27
|
eos
|
@@ -36,6 +54,7 @@ eos
|
|
36
54
|
entry.mount_options = 'defaults'
|
37
55
|
entry.dumpable = 1
|
38
56
|
entry.fsck_order = 1
|
57
|
+
LinuxAdmin::FSTab.any_instance.stub(:refresh) # don't read /etc/fstab
|
39
58
|
LinuxAdmin::FSTab.instance.entries = [entry]
|
40
59
|
|
41
60
|
File.should_receive(:write).with('/etc/fstab', "/dev/sda1 / ext4 defaults 1 1\n")
|
data/spec/logical_volume_spec.rb
CHANGED
@@ -5,12 +5,12 @@ describe LinuxAdmin::LogicalVolume do
|
|
5
5
|
LinuxAdmin::Distro.stub(:local => LinuxAdmin::Distros::Test.new)
|
6
6
|
|
7
7
|
@logical_volumes = <<eos
|
8
|
-
/dev/vg_foobar/lv_swap:vg_foobar:3:1:-1:2:4128768:63:-1:0:-1:253:0
|
9
|
-
/dev/vg_foobar/lv_root:vg_foobar:3:1:-1:1:19988480:305:-1:0:-1:253:1
|
8
|
+
/dev/vg_foobar/lv_swap:vg_foobar:3:1:-1:2:4128768:63:-1:0:-1:253:0
|
9
|
+
/dev/vg_foobar/lv_root:vg_foobar:3:1:-1:1:19988480:305:-1:0:-1:253:1
|
10
10
|
eos
|
11
11
|
|
12
12
|
@groups = <<eos
|
13
|
-
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
13
|
+
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
14
14
|
eos
|
15
15
|
end
|
16
16
|
|
@@ -51,13 +51,37 @@ eos
|
|
51
51
|
:params => { '-n' => 'lv',
|
52
52
|
nil => 'vg',
|
53
53
|
'-L' => '256G' })
|
54
|
-
described_class.create 'lv', @vg,
|
54
|
+
described_class.create 'lv', @vg, 256.gigabytes
|
55
|
+
end
|
56
|
+
|
57
|
+
context "size is specified" do
|
58
|
+
it "passes -L option to lvcreate" do
|
59
|
+
described_class.instance_variable_set(:@lvs, [])
|
60
|
+
described_class.should_receive(:run!).
|
61
|
+
with(LinuxAdmin.cmd(:lvcreate),
|
62
|
+
:params => { '-n' => 'lv',
|
63
|
+
nil => 'vg',
|
64
|
+
'-L' => '256G' })
|
65
|
+
described_class.create 'lv', @vg, 256.gigabytes
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "extents is specified" do
|
70
|
+
it "passes -l option to lvcreate" do
|
71
|
+
described_class.instance_variable_set(:@lvs, [])
|
72
|
+
described_class.should_receive(:run!).
|
73
|
+
with(LinuxAdmin.cmd(:lvcreate),
|
74
|
+
:params => { '-n' => 'lv',
|
75
|
+
nil => 'vg',
|
76
|
+
'-l' => '100%FREE' })
|
77
|
+
described_class.create 'lv', @vg, 100
|
78
|
+
end
|
55
79
|
end
|
56
80
|
|
57
81
|
it "returns new logical volume" do
|
58
82
|
LinuxAdmin::VolumeGroup.stub(:run! => double(:output => ""))
|
59
83
|
described_class.stub(:run! => double(:output => ""))
|
60
|
-
lv = described_class.create 'lv', @vg,
|
84
|
+
lv = described_class.create 'lv', @vg, 256.gigabytes
|
61
85
|
lv.should be_an_instance_of(described_class)
|
62
86
|
lv.name.should == 'lv'
|
63
87
|
end
|
@@ -65,7 +89,7 @@ eos
|
|
65
89
|
it "adds logical volume to local registry" do
|
66
90
|
LinuxAdmin::VolumeGroup.stub(:run! => double(:output => ""))
|
67
91
|
described_class.stub(:run! => double(:output => ""))
|
68
|
-
lv = described_class.create 'lv', @vg,
|
92
|
+
lv = described_class.create 'lv', @vg, 256.gigabytes
|
69
93
|
described_class.scan.should include(lv)
|
70
94
|
end
|
71
95
|
end
|
@@ -5,11 +5,11 @@ describe LinuxAdmin::PhysicalVolume do
|
|
5
5
|
LinuxAdmin::Distro.stub(:local => LinuxAdmin::Distros::Test.new)
|
6
6
|
|
7
7
|
@physical_volumes = <<eos
|
8
|
-
/dev/vda2:vg_foobar:24139776:-1:8:8:-1:32768:368:0:368:pxR32D-YkC2-PfHe-zOwb-eaGD-9Ar0-mAOl9u
|
8
|
+
/dev/vda2:vg_foobar:24139776:-1:8:8:-1:32768:368:0:368:pxR32D-YkC2-PfHe-zOwb-eaGD-9Ar0-mAOl9u
|
9
9
|
eos
|
10
10
|
|
11
11
|
@groups = <<eos
|
12
|
-
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
12
|
+
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
13
13
|
eos
|
14
14
|
end
|
15
15
|
|
data/spec/service_spec.rb
CHANGED
@@ -37,8 +37,8 @@ describe LinuxAdmin::Service do
|
|
37
37
|
describe "#enable" do
|
38
38
|
it "enables service" do
|
39
39
|
@service.should_receive(:run!).
|
40
|
-
with(@service.cmd(:
|
41
|
-
:params => { nil => [ '
|
40
|
+
with(@service.cmd(:chkconfig),
|
41
|
+
:params => { nil => [ 'foo', 'on']})
|
42
42
|
@service.enable
|
43
43
|
end
|
44
44
|
|
@@ -51,8 +51,8 @@ describe LinuxAdmin::Service do
|
|
51
51
|
describe "#disable" do
|
52
52
|
it "disable service" do
|
53
53
|
@service.should_receive(:run!).
|
54
|
-
with(@service.cmd(:
|
55
|
-
:params => { nil => [ '
|
54
|
+
with(@service.cmd(:chkconfig),
|
55
|
+
:params => { nil => [ 'foo', 'off']})
|
56
56
|
@service.disable
|
57
57
|
end
|
58
58
|
|
data/spec/volume_group_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe LinuxAdmin::VolumeGroup do
|
|
5
5
|
LinuxAdmin::Distro.stub(:local => LinuxAdmin::Distros::Test.new)
|
6
6
|
|
7
7
|
@groups = <<eos
|
8
|
-
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
8
|
+
vg_foobar:r/w:772:-1:0:2:2:-1:0:1:1:12058624:32768:368:368:0:tILZUF-IspH-H90I-pT5j-vVFl-b76L-zWx3CW
|
9
9
|
eos
|
10
10
|
end
|
11
11
|
|
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.2
|
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-
|
15
|
+
date: 2013-09-06 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bundler
|