linux_admin 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/linux_admin/common.rb +5 -12
- data/lib/linux_admin/disk.rb +82 -16
- data/lib/linux_admin/distro.rb +18 -7
- data/lib/linux_admin/exceptions.rb +1 -0
- data/lib/linux_admin/fstab.rb +9 -0
- data/lib/linux_admin/logical_volume.rb +65 -1
- data/lib/linux_admin/partition.rb +12 -4
- data/lib/linux_admin/physical_volume.rb +75 -0
- data/lib/linux_admin/{rhn.rb → registration_system/rhn.rb} +10 -8
- data/lib/linux_admin/registration_system/subscription_manager.rb +89 -0
- data/lib/linux_admin/registration_system.rb +45 -0
- data/lib/linux_admin/version.rb +1 -1
- data/lib/linux_admin/volume_group.rb +73 -0
- data/lib/linux_admin/yum.rb +1 -1
- data/lib/linux_admin.rb +6 -16
- data/linux_admin.gemspec +6 -2
- data/spec/common_spec.rb +39 -34
- data/spec/data/subscription_manager/output_orgs +6 -0
- data/spec/disk_spec.rb +117 -0
- data/spec/distro_spec.rb +1 -1
- data/spec/fstab_spec.rb +18 -0
- data/spec/linux_admin_spec.rb +0 -38
- data/spec/logical_volume_spec.rb +108 -0
- data/spec/partition_spec.rb +15 -0
- data/spec/physical_volume_spec.rb +110 -0
- data/spec/registration_system_spec.rb +60 -0
- data/spec/rhn_spec.rb +17 -21
- data/spec/spec_helper.rb +12 -0
- data/spec/subscription_manager_spec.rb +23 -18
- data/spec/volume_group_spec.rb +108 -0
- data/spec/yum_spec.rb +1 -1
- metadata +25 -5
- data/lib/linux_admin/subscription_manager.rb +0 -61
data/lib/linux_admin/common.rb
CHANGED
@@ -1,16 +1,7 @@
|
|
1
1
|
require 'shellwords'
|
2
2
|
|
3
3
|
class LinuxAdmin
|
4
|
-
class CommandError < RuntimeError; end
|
5
|
-
|
6
4
|
module Common
|
7
|
-
def write(file, content)
|
8
|
-
raise ArgumentError, "file and content can not be empty" if file.blank? || content.blank?
|
9
|
-
File.open(file, "w") do |f|
|
10
|
-
f.write(content)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
5
|
def cmd(cmd)
|
15
6
|
Distro.local.class::COMMANDS[cmd]
|
16
7
|
end
|
@@ -19,7 +10,9 @@ class LinuxAdmin
|
|
19
10
|
params = options[:params] || options[:parameters]
|
20
11
|
|
21
12
|
begin
|
22
|
-
|
13
|
+
launch_params = {}
|
14
|
+
launch_params[:chdir] = options[:chdir] if options[:chdir]
|
15
|
+
out = launch(build_cmd(cmd, params), launch_params)
|
23
16
|
|
24
17
|
if options[:return_output] && exitstatus == 0
|
25
18
|
out
|
@@ -67,9 +60,9 @@ class LinuxAdmin
|
|
67
60
|
# http://stackoverflow.com/questions/13829830/ruby-process-spawn-stdout-pipe-buffer-size-limit/13846146#13846146
|
68
61
|
THREAD_SYNC_KEY = "LinuxAdmin-exitstatus"
|
69
62
|
|
70
|
-
def launch(cmd)
|
63
|
+
def launch(cmd, spawn_options = {})
|
71
64
|
pipe_r, pipe_w = IO.pipe
|
72
|
-
pid = Kernel.spawn(cmd, :err => [:child, :out], :out => pipe_w)
|
65
|
+
pid = Kernel.spawn(cmd, {:err => [:child, :out], :out => pipe_w}.merge(spawn_options))
|
73
66
|
wait_for_process(pid, pipe_w)
|
74
67
|
wait_for_output(pipe_r)
|
75
68
|
end
|
data/lib/linux_admin/disk.rb
CHANGED
@@ -19,33 +19,72 @@ class LinuxAdmin
|
|
19
19
|
@path = args[:path]
|
20
20
|
end
|
21
21
|
|
22
|
+
def size
|
23
|
+
@size ||= begin
|
24
|
+
size = nil
|
25
|
+
out = run(cmd(:fdisk),
|
26
|
+
:return_output => true,
|
27
|
+
:params => {"-l" => nil})
|
28
|
+
out.each_line { |l|
|
29
|
+
if l =~ /Disk #{path}: ([0-9\.]*) ([KMG])B.*/
|
30
|
+
size = case $2
|
31
|
+
when 'K' then
|
32
|
+
$1.to_f.kilobytes
|
33
|
+
when 'M' then
|
34
|
+
$1.to_f.megabytes
|
35
|
+
when 'G' then
|
36
|
+
$1.to_f.gigabytes
|
37
|
+
end
|
38
|
+
break
|
39
|
+
end
|
40
|
+
}
|
41
|
+
size
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
22
45
|
def partitions
|
23
46
|
@partitions ||= begin
|
24
47
|
partitions = []
|
25
48
|
|
26
49
|
# requires sudo
|
27
50
|
out = run(cmd(:parted),
|
51
|
+
:return_exitstatus => true,
|
28
52
|
:return_output => true,
|
29
53
|
:params => { nil => [@path, 'print'] })
|
30
54
|
|
55
|
+
return [] if out.kind_of?(Fixnum)
|
56
|
+
|
31
57
|
out.each_line do |l|
|
32
58
|
if l =~ /^ [0-9].*/
|
33
59
|
p = l.split
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
60
|
+
args = {:disk => self}
|
61
|
+
fields = [:id, :start_sector, :end_sector,
|
62
|
+
:size, :partition_type, :fs_type]
|
63
|
+
|
64
|
+
fields.each_index do |i|
|
65
|
+
val = p[i]
|
66
|
+
case fields[i]
|
67
|
+
when :start_sector, :end_sector, :size
|
68
|
+
if val =~ /([0-9\.]*)([KMG])B/
|
69
|
+
val = case $2
|
70
|
+
when 'K' then
|
71
|
+
$1.to_f.kilobytes
|
72
|
+
when 'M' then
|
73
|
+
$1.to_f.megabytes
|
74
|
+
when 'G' then
|
75
|
+
$1.to_f.gigabytes
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
when :id
|
80
|
+
val = val.to_i
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
args[fields[i]] = val
|
44
85
|
end
|
45
|
-
partitions << Partition.new(
|
46
|
-
|
47
|
-
:size => size,
|
48
|
-
:fs_type => fs_type)
|
86
|
+
partitions << Partition.new(args)
|
87
|
+
|
49
88
|
end
|
50
89
|
end
|
51
90
|
|
@@ -53,8 +92,35 @@ class LinuxAdmin
|
|
53
92
|
end
|
54
93
|
end
|
55
94
|
|
56
|
-
def create_partition
|
57
|
-
|
95
|
+
def create_partition(partition_type, size)
|
96
|
+
id, start =
|
97
|
+
partitions.empty? ? [1, 0] :
|
98
|
+
[(partitions.last.id + 1),
|
99
|
+
partitions.last.end_sector]
|
100
|
+
|
101
|
+
run(cmd(:parted),
|
102
|
+
:params => { nil => [path, 'mkpart', partition_type,
|
103
|
+
start, start + size]})
|
104
|
+
|
105
|
+
partition = Partition.new(:disk => self,
|
106
|
+
:id => id,
|
107
|
+
:start_sector => start,
|
108
|
+
:end_sector => start+size,
|
109
|
+
:size => size,
|
110
|
+
:partition_type => partition_type)
|
111
|
+
partitions << partition
|
112
|
+
partition
|
113
|
+
end
|
114
|
+
|
115
|
+
def clear!
|
116
|
+
@partitions = []
|
117
|
+
|
118
|
+
# clear partition table
|
119
|
+
run(cmd(:dd),
|
120
|
+
:params => { 'if=' => '/dev/zero', 'of=' => @path,
|
121
|
+
'bs=' => 512, 'count=' => 1})
|
122
|
+
|
123
|
+
self
|
58
124
|
end
|
59
125
|
end
|
60
126
|
end
|
data/lib/linux_admin/distro.rb
CHANGED
@@ -17,7 +17,7 @@ class LinuxAdmin
|
|
17
17
|
issue = File.read('/etc/issue')
|
18
18
|
if issue.include?('ubuntu')
|
19
19
|
return Distros.ubuntu
|
20
|
-
elsif ['Fedora', 'red hat', 'centos'].any? { |d| issue.include?(d) }
|
20
|
+
elsif ['Fedora', 'red hat', 'Red Hat', 'centos'].any? { |d| issue.include?(d) }
|
21
21
|
return Distros.redhat
|
22
22
|
end
|
23
23
|
|
@@ -58,12 +58,23 @@ class LinuxAdmin
|
|
58
58
|
end
|
59
59
|
|
60
60
|
class RedHat < Distro
|
61
|
-
COMMANDS = {:service => '/
|
62
|
-
:systemctl => '/
|
63
|
-
:parted => '/
|
64
|
-
:mount => '/
|
65
|
-
:umount => '/
|
66
|
-
:shutdown => '/
|
61
|
+
COMMANDS = {:service => '/sbin/service',
|
62
|
+
:systemctl => '/bin/systemctl',
|
63
|
+
:parted => '/sbin/parted',
|
64
|
+
:mount => '/bin/mount',
|
65
|
+
:umount => '/bin/umount',
|
66
|
+
:shutdown => '/sbin/shutdown',
|
67
|
+
:mke2fs => '/sbin/mke2fs',
|
68
|
+
:fdisk => '/sbin/fdisk',
|
69
|
+
:dd => '/bin/dd',
|
70
|
+
:vgdisplay => '/sbin/vgdisplay',
|
71
|
+
:pvdisplay => '/sbin/pvdisplay',
|
72
|
+
:lvdisplay => '/sbin/lvdisplay',
|
73
|
+
:lvextend => '/sbin/lvextend',
|
74
|
+
:vgextend => '/sbin/vgextend',
|
75
|
+
:lvcreate => '/sbin/lvcreate',
|
76
|
+
:pvcreate => '/sbin/pvcreate',
|
77
|
+
:vgcreate => '/sbin/vgcreate'}
|
67
78
|
|
68
79
|
def initialize
|
69
80
|
@id = :redhat
|
@@ -0,0 +1 @@
|
|
1
|
+
class CommandError < RuntimeError; end
|
data/lib/linux_admin/fstab.rb
CHANGED
@@ -24,6 +24,15 @@ class LinuxAdmin
|
|
24
24
|
refresh
|
25
25
|
end
|
26
26
|
|
27
|
+
def write!
|
28
|
+
content = ''
|
29
|
+
@entries.each do |entry|
|
30
|
+
content += "#{entry.device} #{entry.mount_point} #{entry.fs_type} #{entry.mount_options} #{entry.dumpable} #{entry.fsck_order}\n"
|
31
|
+
end
|
32
|
+
File.write('/etc/fstab', content)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
27
36
|
private
|
28
37
|
|
29
38
|
def refresh
|
@@ -5,7 +5,71 @@
|
|
5
5
|
|
6
6
|
class LinuxAdmin
|
7
7
|
class LogicalVolume < LinuxAdmin
|
8
|
-
|
8
|
+
# logical volume name
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# volume group name
|
12
|
+
attr_accessor :volume_group
|
13
|
+
|
14
|
+
# logical volume size in sectors
|
15
|
+
attr_accessor :sectors
|
16
|
+
|
17
|
+
# other fields available:
|
18
|
+
# logical volume access
|
19
|
+
# logical volume status
|
20
|
+
# internal logical volume number
|
21
|
+
# open count of logical volume
|
22
|
+
# current logical extents associated to logical volume
|
23
|
+
# allocated logical extents of logical volume
|
24
|
+
# allocation policy of logical volume
|
25
|
+
# read ahead sectors of logical volume
|
26
|
+
# major device number of logical volume
|
27
|
+
# minor device number of logical volume
|
28
|
+
|
29
|
+
def initialize(args = {})
|
30
|
+
@name = args[:name]
|
31
|
+
@volume_group = args[:volume_group]
|
32
|
+
@sectors = args[:sectors]
|
33
|
+
end
|
34
|
+
|
35
|
+
def extend_with(vg)
|
36
|
+
run(cmd(:lvextend),
|
37
|
+
:params => [self.name, vg.name])
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.create(name, vg, size)
|
42
|
+
self.scan # initialize local logical volumes
|
43
|
+
run(cmd(:lvcreate),
|
44
|
+
:params => { '-n' => name, nil => vg.name, '-L' => size})
|
45
|
+
lv = LogicalVolume.new :name => name,
|
46
|
+
:volume_group => vg,
|
47
|
+
:sectors => size
|
48
|
+
@lvs << lv
|
49
|
+
lv
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.scan
|
53
|
+
@lvs ||= begin
|
54
|
+
vgs = VolumeGroup.scan
|
55
|
+
lvs = []
|
56
|
+
|
57
|
+
out = run(cmd(:lvdisplay),
|
58
|
+
:return_output => true,
|
59
|
+
:params => { '-c' => nil})
|
60
|
+
|
61
|
+
out.each_line do |line|
|
62
|
+
fields = line.split(':')
|
63
|
+
vgname = fields[1]
|
64
|
+
vg = vgs.find { |vg| vg.name == vgname }
|
65
|
+
|
66
|
+
lvs << LogicalVolume.new(:name => fields[0],
|
67
|
+
:volume_group => vg,
|
68
|
+
:sectors => fields[6].to_i)
|
69
|
+
end
|
70
|
+
|
71
|
+
lvs
|
72
|
+
end
|
9
73
|
end
|
10
74
|
end
|
11
75
|
end
|
@@ -8,7 +8,10 @@ require 'fileutils'
|
|
8
8
|
class LinuxAdmin
|
9
9
|
class Partition < LinuxAdmin
|
10
10
|
attr_accessor :id
|
11
|
+
attr_accessor :partition_type
|
11
12
|
attr_accessor :fs_type
|
13
|
+
attr_accessor :start_sector
|
14
|
+
attr_accessor :end_sector
|
12
15
|
attr_accessor :size
|
13
16
|
attr_accessor :disk
|
14
17
|
attr_accessor :mount_point
|
@@ -18,12 +21,21 @@ class LinuxAdmin
|
|
18
21
|
@size = args[:size]
|
19
22
|
@disk = args[:disk]
|
20
23
|
@fs_type = args[:fs_type]
|
24
|
+
@start_sector = args[:start_sector]
|
25
|
+
@end_sector = args[:end_sector]
|
26
|
+
@partition_type = args[:partition_type]
|
21
27
|
end
|
22
28
|
|
23
29
|
def path
|
24
30
|
"#{disk.path}#{id}"
|
25
31
|
end
|
26
32
|
|
33
|
+
def format_to(filesystem)
|
34
|
+
run(cmd(:mke2fs),
|
35
|
+
:params => { '-t' => filesystem, nil => self.path})
|
36
|
+
@fs_type = filesystem
|
37
|
+
end
|
38
|
+
|
27
39
|
def mount(mount_point=nil)
|
28
40
|
@mount_point = mount_point
|
29
41
|
@mount_point =
|
@@ -38,9 +50,5 @@ class LinuxAdmin
|
|
38
50
|
run(cmd(:umount),
|
39
51
|
:params => { nil => [@mount_point] })
|
40
52
|
end
|
41
|
-
|
42
|
-
def format_to(fs_type)
|
43
|
-
#TODO
|
44
|
-
end
|
45
53
|
end
|
46
54
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# LinuxAdmin Physical Volume Representation
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Red Hat Inc.
|
4
|
+
# Licensed under the MIT License
|
5
|
+
|
6
|
+
class LinuxAdmin
|
7
|
+
class PhysicalVolume < LinuxAdmin
|
8
|
+
# physical volume device name
|
9
|
+
attr_accessor :device_name
|
10
|
+
|
11
|
+
# volume group name
|
12
|
+
attr_accessor :volume_group
|
13
|
+
|
14
|
+
# physical volume size in kilobytes
|
15
|
+
attr_accessor :size
|
16
|
+
|
17
|
+
# other fields available
|
18
|
+
# internal physical volume number (obsolete)
|
19
|
+
# physical volume status
|
20
|
+
# physical volume (not) allocatable
|
21
|
+
# current number of logical volumes on this physical volume
|
22
|
+
# physical extent size in kilobytes
|
23
|
+
# total number of physical extents
|
24
|
+
# free number of physical extents
|
25
|
+
# allocated number of physical extents
|
26
|
+
|
27
|
+
def initialize(args = {})
|
28
|
+
@device_name = args[:device_name]
|
29
|
+
@volume_group = args[:volume_group]
|
30
|
+
@size = args[:size]
|
31
|
+
end
|
32
|
+
|
33
|
+
def attach_to(vg)
|
34
|
+
run(cmd(:vgextend),
|
35
|
+
:params => [vg.name, @device_name])
|
36
|
+
self.volume_group = vg
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# specify disk or partition instance to create physical volume on
|
41
|
+
def self.create(device)
|
42
|
+
self.scan # initialize local physical volumes
|
43
|
+
run(cmd(:pvcreate),
|
44
|
+
:params => { nil => device.path})
|
45
|
+
pv = PhysicalVolume.new(:device_name => device.path,
|
46
|
+
:volume_group => nil,
|
47
|
+
:size => device.size)
|
48
|
+
@pvs << pv
|
49
|
+
pv
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.scan
|
53
|
+
@pvs ||= begin
|
54
|
+
vgs = VolumeGroup.scan
|
55
|
+
pvs = []
|
56
|
+
|
57
|
+
out = run(cmd(:pvdisplay),
|
58
|
+
:return_output => true,
|
59
|
+
:params => { '-c' => nil})
|
60
|
+
|
61
|
+
out.each_line do |line|
|
62
|
+
fields = line.split(':')
|
63
|
+
vgname = fields[1]
|
64
|
+
vg = vgs.find { |vg| vg.name == vgname}
|
65
|
+
|
66
|
+
pvs << PhysicalVolume.new(:device_name => fields[0],
|
67
|
+
:volume_group => vg,
|
68
|
+
:size => fields[2].to_i)
|
69
|
+
end
|
70
|
+
|
71
|
+
pvs
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,12 +1,8 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
|
3
3
|
class LinuxAdmin
|
4
|
-
class Rhn <
|
5
|
-
def
|
6
|
-
"/etc/sysconfig/rhn/systemid"
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.registered?
|
4
|
+
class Rhn < RegistrationSystem
|
5
|
+
def registered?
|
10
6
|
id = ""
|
11
7
|
if File.exists?(systemid_file)
|
12
8
|
xml = Nokogiri.XML(File.read(systemid_file))
|
@@ -15,7 +11,7 @@ class LinuxAdmin
|
|
15
11
|
id.length > 0
|
16
12
|
end
|
17
13
|
|
18
|
-
def
|
14
|
+
def register(options)
|
19
15
|
cmd = "rhnreg_ks"
|
20
16
|
params = {}
|
21
17
|
|
@@ -36,7 +32,7 @@ class LinuxAdmin
|
|
36
32
|
run(cmd, :params => params)
|
37
33
|
end
|
38
34
|
|
39
|
-
def
|
35
|
+
def subscribe(options)
|
40
36
|
raise ArgumentError, "pools, username and password are required" if options[:pools].blank? || options[:username].blank? || options[:password].blank?
|
41
37
|
cmd = "rhn-channel -a"
|
42
38
|
|
@@ -49,5 +45,11 @@ class LinuxAdmin
|
|
49
45
|
|
50
46
|
run(cmd, :params => params)
|
51
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def systemid_file
|
52
|
+
"/etc/sysconfig/rhn/systemid"
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class LinuxAdmin
|
4
|
+
class SubscriptionManager < RegistrationSystem
|
5
|
+
|
6
|
+
def validate_credentials(options)
|
7
|
+
!!organizations(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def registered?
|
11
|
+
run("subscription-manager identity", :return_exitstatus => true) == 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def refresh
|
15
|
+
run("subscription-manager refresh")
|
16
|
+
end
|
17
|
+
|
18
|
+
def organizations(options)
|
19
|
+
raise ArgumentError, "username and password are required" unless options[:username] && options[:password]
|
20
|
+
cmd = "subscription-manager orgs"
|
21
|
+
|
22
|
+
params = {"--username=" => options[:username], "--password=" => options[:password]}
|
23
|
+
params.merge!(proxy_params(options))
|
24
|
+
params["--serverurl="] = options[:server_url] if options[:server_url]
|
25
|
+
|
26
|
+
output = run(cmd, :params => params, :return_output => true)
|
27
|
+
parse_output(output).index_by {|i| i[:name]}
|
28
|
+
end
|
29
|
+
|
30
|
+
def register(options)
|
31
|
+
raise ArgumentError, "username and password are required" unless options[:username] && options[:password]
|
32
|
+
cmd = "subscription-manager register"
|
33
|
+
|
34
|
+
params = {"--username=" => options[:username], "--password=" => options[:password]}
|
35
|
+
params.merge!(proxy_params(options))
|
36
|
+
params["--org="] = options[:org] if options[:server_url] && options[:org]
|
37
|
+
params["--serverurl="] = options[:server_url] if options[:server_url]
|
38
|
+
|
39
|
+
run(cmd, :params => params)
|
40
|
+
end
|
41
|
+
|
42
|
+
def subscribe(options)
|
43
|
+
cmd = "subscription-manager attach"
|
44
|
+
pools = options[:pools].collect {|pool| ["--pool", pool]}
|
45
|
+
params = proxy_params(options).to_a + pools
|
46
|
+
|
47
|
+
run(cmd, :params => params)
|
48
|
+
end
|
49
|
+
|
50
|
+
def available_subscriptions
|
51
|
+
cmd = "subscription-manager list --all --available"
|
52
|
+
output = run(cmd, :return_output => true)
|
53
|
+
parse_output(output).index_by {|i| i[:pool_id]}
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def parse_output(output)
|
59
|
+
# Strip the 3 line header off the top
|
60
|
+
content = output.split("\n")[3..-1].join("\n")
|
61
|
+
parse_content(content)
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_content(content)
|
65
|
+
# Break into content groupings by "\n\n" then process each grouping
|
66
|
+
content.split("\n\n").each_with_object([]) do |group, group_array|
|
67
|
+
group = group.split("\n").each_with_object({}) do |line, hash|
|
68
|
+
next if line.blank?
|
69
|
+
key, value = line.split(":", 2)
|
70
|
+
hash[key.strip.downcase.tr(" -", "_").to_sym] = value.strip
|
71
|
+
end
|
72
|
+
group_array.push(format_values(group))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def format_values(content_group)
|
77
|
+
content_group[:ends] = Date.strptime(content_group[:ends], "%m/%d/%Y") if content_group[:ends]
|
78
|
+
content_group
|
79
|
+
end
|
80
|
+
|
81
|
+
def proxy_params(options)
|
82
|
+
config = {}
|
83
|
+
config["--proxy="] = options[:proxy_address] if options[:proxy_address]
|
84
|
+
config["--proxyuser="] = options[:proxy_username] if options[:proxy_username]
|
85
|
+
config["--proxypassword="] = options[:proxy_password] if options[:proxy_password]
|
86
|
+
config
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class LinuxAdmin
|
2
|
+
class RegistrationSystem < LinuxAdmin
|
3
|
+
def self.registration_type(reload = false)
|
4
|
+
return @registration_type if @registration_type && !reload
|
5
|
+
@registration_type = registration_type_uncached
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.method_missing(meth, *args, &block)
|
9
|
+
if white_list_methods.include?(meth)
|
10
|
+
r = self.registration_type.new
|
11
|
+
raise NotImplementedError, "#{meth} not implemented for #{self.name}" unless r.respond_to?(meth)
|
12
|
+
r.send(meth, *args, &block)
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def registered?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.registration_type_uncached
|
25
|
+
if SubscriptionManager.new.registered?
|
26
|
+
SubscriptionManager
|
27
|
+
elsif Rhn.new.registered?
|
28
|
+
Rhn
|
29
|
+
else
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
private_class_method :registration_type_uncached
|
34
|
+
|
35
|
+
def self.white_list_methods
|
36
|
+
@white_list_methods ||= begin
|
37
|
+
all_methods = RegistrationSystem.instance_methods(false) + Rhn.instance_methods(false) + SubscriptionManager.instance_methods(false)
|
38
|
+
all_methods.uniq
|
39
|
+
end
|
40
|
+
end
|
41
|
+
private_class_method :white_list_methods
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Dir.glob(File.join(File.dirname(__FILE__), "registration_system", "*.rb")).each { |f| require f }
|
data/lib/linux_admin/version.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
# LinuxAdmin Volume Group Representation
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Red Hat Inc.
|
4
|
+
# Licensed under the MIT License
|
5
|
+
|
6
|
+
class LinuxAdmin
|
7
|
+
class VolumeGroup < LinuxAdmin
|
8
|
+
# volume group name
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
# other fields available
|
12
|
+
# volume group access
|
13
|
+
# volume group status
|
14
|
+
# internal volume group number
|
15
|
+
# maximum number of logical volumes
|
16
|
+
# current number of logical volumes
|
17
|
+
# open count of all logical volumes in this volume group
|
18
|
+
# maximum logical volume size
|
19
|
+
# maximum number of physical volumes
|
20
|
+
# current number of physical volumes
|
21
|
+
# actual number of physical volumes
|
22
|
+
# size of volume group in kilobytes
|
23
|
+
# physical extent size
|
24
|
+
# total number of physical extents for this volume group
|
25
|
+
# allocated number of physical extents for this volume group
|
26
|
+
# free number of physical extents for this volume group
|
27
|
+
# uuid of volume group
|
28
|
+
|
29
|
+
def initialize(args = {})
|
30
|
+
@name = args[:name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def attach_to(lv)
|
34
|
+
run(cmd(:lvextend),
|
35
|
+
:params => [lv.name, self.name])
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def extend_with(pv)
|
40
|
+
run(cmd(:vgextend),
|
41
|
+
:params => [@name, pv.device_name])
|
42
|
+
pv.volume_group = self
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.create(name, pv)
|
47
|
+
self.scan # initialize local volume groups
|
48
|
+
run(cmd(:vgcreate),
|
49
|
+
:params => [name, pv.device_name])
|
50
|
+
vg = VolumeGroup.new :name => name
|
51
|
+
pv.volume_group = vg
|
52
|
+
@vgs << vg
|
53
|
+
vg
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.scan
|
57
|
+
@vgs ||= begin
|
58
|
+
vgs = []
|
59
|
+
|
60
|
+
out = run(cmd(:vgdisplay),
|
61
|
+
:return_output => true,
|
62
|
+
:params => { '-c' => nil})
|
63
|
+
|
64
|
+
out.each_line do |line|
|
65
|
+
fields = line.split(':')
|
66
|
+
vgs << VolumeGroup.new(:name => fields[0])
|
67
|
+
end
|
68
|
+
|
69
|
+
vgs
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/linux_admin/yum.rb
CHANGED
@@ -59,7 +59,7 @@ class LinuxAdmin
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.version_available(*packages)
|
62
|
-
raise ArgumentError, "packages requires at least one package name"
|
62
|
+
raise ArgumentError, "packages requires at least one package name" if packages.blank?
|
63
63
|
|
64
64
|
cmd = "repoquery --qf=\"%{name} %{version}\""
|
65
65
|
params = {nil => packages}
|