linux_admin 0.2.1 → 0.2.2
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 +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
|