linux_admin 0.1.3 → 0.2.0

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.rb CHANGED
@@ -5,6 +5,7 @@ require 'linux_admin/registration_system'
5
5
 
6
6
  require 'linux_admin/common'
7
7
  require 'linux_admin/exceptions'
8
+ require 'linux_admin/command_result'
8
9
  require 'linux_admin/rpm'
9
10
  require 'linux_admin/version'
10
11
  require 'linux_admin/yum'
@@ -0,0 +1,9 @@
1
+ class CommandResult
2
+ attr_reader :output, :error, :exit_status
3
+
4
+ def initialize(output, error, exit_status)
5
+ @output = output
6
+ @error = error
7
+ @exit_status = exit_status
8
+ end
9
+ end
@@ -9,24 +9,35 @@ class LinuxAdmin
9
9
  def run(cmd, options = {})
10
10
  params = options[:params] || options[:parameters]
11
11
 
12
+ launch_params = {}
13
+ launch_params[:chdir] = options[:chdir] if options[:chdir]
14
+
15
+ output = ""
16
+ error = ""
17
+ status = nil
18
+
12
19
  begin
13
- launch_params = {}
14
- launch_params[:chdir] = options[:chdir] if options[:chdir]
15
- out = launch(build_cmd(cmd, params), launch_params)
16
-
17
- if options[:return_output] && exitstatus == 0
18
- out
19
- elsif options[:return_exitstatus] || exitstatus == 0
20
- exitstatus
21
- else
22
- raise CommandError, "#{build_cmd(cmd, params)}: exit code: #{exitstatus}"
23
- end
24
- rescue
25
- return nil if options[:return_exitstatus]
26
- raise
20
+ output, error = launch(build_cmd(cmd, params), launch_params)
21
+ status = exitstatus
27
22
  ensure
23
+ output ||= ""
24
+ error ||= ""
28
25
  self.exitstatus = nil
29
26
  end
27
+
28
+ CommandResult.new(output, error, status)
29
+ end
30
+
31
+ def run!(cmd, options = {})
32
+ params = options[:params] || options[:parameters]
33
+ command_result = run(cmd, options)
34
+
35
+ if command_result.exit_status != 0
36
+ message = "#{cmd} exit code: #{command_result.exit_status}"
37
+ raise CommandResultError.new(message, command_result)
38
+ end
39
+
40
+ command_result
30
41
  end
31
42
 
32
43
  private
@@ -61,25 +72,28 @@ class LinuxAdmin
61
72
  THREAD_SYNC_KEY = "LinuxAdmin-exitstatus"
62
73
 
63
74
  def launch(cmd, spawn_options = {})
64
- pipe_r, pipe_w = IO.pipe
65
- pid = Kernel.spawn(cmd, {:err => [:child, :out], :out => pipe_w}.merge(spawn_options))
66
- wait_for_process(pid, pipe_w)
67
- wait_for_output(pipe_r)
75
+ out_r, out_w = IO.pipe
76
+ err_r, err_w = IO.pipe
77
+ pid = Kernel.spawn(cmd, {:err => err_w, :out => out_w}.merge(spawn_options))
78
+ wait_for_process(pid, out_w, err_w)
79
+ wait_for_pipes(out_r, err_r)
68
80
  end
69
81
 
70
- def wait_for_process(pid, pipe_w)
82
+ def wait_for_process(pid, out_w, err_w)
71
83
  self.exitstatus = :not_done
72
84
  Thread.new(Thread.current) do |parent_thread|
73
85
  _, status = Process.wait2(pid)
74
- pipe_w.close
86
+ out_w.close
87
+ err_w.close
75
88
  parent_thread[THREAD_SYNC_KEY] = status.exitstatus
76
89
  end
77
90
  end
78
91
 
79
- def wait_for_output(pipe_r)
80
- out = pipe_r.read
92
+ def wait_for_pipes(out_r, err_r)
93
+ out = out_r.read
94
+ err = err_r.read
81
95
  sleep(0.1) while exitstatus == :not_done
82
- return out
96
+ return out, err
83
97
  end
84
98
 
85
99
  def exitstatus
@@ -22,9 +22,7 @@ class LinuxAdmin
22
22
  def size
23
23
  @size ||= begin
24
24
  size = nil
25
- out = run(cmd(:fdisk),
26
- :return_output => true,
27
- :params => {"-l" => nil})
25
+ out = run!(cmd(:fdisk), :params => {"-l" => nil}).output
28
26
  out.each_line { |l|
29
27
  if l =~ /Disk #{path}: ([0-9\.]*) ([KMG])B.*/
30
28
  size = case $2
@@ -46,13 +44,11 @@ class LinuxAdmin
46
44
  @partitions ||= begin
47
45
  partitions = []
48
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
49
  # requires sudo
50
50
  out = run(cmd(:parted),
51
- :return_exitstatus => true,
52
- :return_output => true,
53
- :params => { nil => [@path, 'print'] })
54
-
55
- return [] if out.kind_of?(Fixnum)
51
+ :params => { nil => [@path, 'print'] }).output
56
52
 
57
53
  out.each_line do |l|
58
54
  if l =~ /^ [0-9].*/
@@ -98,7 +94,7 @@ class LinuxAdmin
98
94
  [(partitions.last.id + 1),
99
95
  partitions.last.end_sector]
100
96
 
101
- run(cmd(:parted),
97
+ run!(cmd(:parted),
102
98
  :params => { nil => [path, 'mkpart', partition_type,
103
99
  start, start + size]})
104
100
 
@@ -116,7 +112,7 @@ class LinuxAdmin
116
112
  @partitions = []
117
113
 
118
114
  # clear partition table
119
- run(cmd(:dd),
115
+ run!(cmd(:dd),
120
116
  :params => { 'if=' => '/dev/zero', 'of=' => @path,
121
117
  'bs=' => 512, 'count=' => 1})
122
118
 
@@ -1 +1,16 @@
1
- class CommandError < RuntimeError; end
1
+ class CommandResultError < StandardError
2
+ attr_reader :result
3
+
4
+ def initialize(message, result)
5
+ super(message)
6
+ @result = result
7
+ end
8
+ end
9
+
10
+ class LinuxAdmin
11
+ class CredentialError < CommandResultError
12
+ def initialize(result)
13
+ super("Invalid username or password", result)
14
+ end
15
+ end
16
+ end
@@ -33,14 +33,14 @@ class LinuxAdmin
33
33
  end
34
34
 
35
35
  def extend_with(vg)
36
- run(cmd(:lvextend),
36
+ run!(cmd(:lvextend),
37
37
  :params => [self.name, vg.name])
38
38
  self
39
39
  end
40
40
 
41
41
  def self.create(name, vg, size)
42
42
  self.scan # initialize local logical volumes
43
- run(cmd(:lvcreate),
43
+ run!(cmd(:lvcreate),
44
44
  :params => { '-n' => name, nil => vg.name, '-L' => size})
45
45
  lv = LogicalVolume.new :name => name,
46
46
  :volume_group => vg,
@@ -54,9 +54,7 @@ class LinuxAdmin
54
54
  vgs = VolumeGroup.scan
55
55
  lvs = []
56
56
 
57
- out = run(cmd(:lvdisplay),
58
- :return_output => true,
59
- :params => { '-c' => nil})
57
+ out = run!(cmd(:lvdisplay), :params => { '-c' => nil}).output
60
58
 
61
59
  out.each_line do |line|
62
60
  fields = line.split(':')
@@ -31,7 +31,7 @@ class LinuxAdmin
31
31
  end
32
32
 
33
33
  def format_to(filesystem)
34
- run(cmd(:mke2fs),
34
+ run!(cmd(:mke2fs),
35
35
  :params => { '-t' => filesystem, nil => self.path})
36
36
  @fs_type = filesystem
37
37
  end
@@ -42,12 +42,12 @@ class LinuxAdmin
42
42
  "/mnt/#{disk.path.split(File::SEPARATOR).last}#{id}" if mount_point.nil?
43
43
  FileUtils.mkdir(@mount_point) unless File.directory?(@mount_point)
44
44
 
45
- run(cmd(:mount),
45
+ run!(cmd(:mount),
46
46
  :params => { nil => [self.path, @mount_point] })
47
47
  end
48
48
 
49
49
  def umount
50
- run(cmd(:umount),
50
+ run!(cmd(:umount),
51
51
  :params => { nil => [@mount_point] })
52
52
  end
53
53
  end
@@ -31,7 +31,7 @@ class LinuxAdmin
31
31
  end
32
32
 
33
33
  def attach_to(vg)
34
- run(cmd(:vgextend),
34
+ run!(cmd(:vgextend),
35
35
  :params => [vg.name, @device_name])
36
36
  self.volume_group = vg
37
37
  self
@@ -40,7 +40,7 @@ class LinuxAdmin
40
40
  # specify disk or partition instance to create physical volume on
41
41
  def self.create(device)
42
42
  self.scan # initialize local physical volumes
43
- run(cmd(:pvcreate),
43
+ run!(cmd(:pvcreate),
44
44
  :params => { nil => device.path})
45
45
  pv = PhysicalVolume.new(:device_name => device.path,
46
46
  :volume_group => nil,
@@ -54,9 +54,7 @@ class LinuxAdmin
54
54
  vgs = VolumeGroup.scan
55
55
  pvs = []
56
56
 
57
- out = run(cmd(:pvdisplay),
58
- :return_output => true,
59
- :params => { '-c' => nil})
57
+ out = run!(cmd(:pvdisplay), :params => { '-c' => nil}).output
60
58
 
61
59
  out.each_line do |line|
62
60
  fields = line.split(':')
@@ -29,7 +29,7 @@ class LinuxAdmin
29
29
  params["--proxyPassword="] = options[:proxy_password] if options[:proxy_password]
30
30
  params["--serverUrl="] = options[:server_url] if options[:server_url]
31
31
 
32
- run(cmd, :params => params)
32
+ run!(cmd, :params => params)
33
33
  end
34
34
 
35
35
  def subscribe(options)
@@ -43,7 +43,7 @@ class LinuxAdmin
43
43
  params["--password="] = options[:password]
44
44
  params = params.to_a + pools
45
45
 
46
- run(cmd, :params => params)
46
+ run!(cmd, :params => params)
47
47
  end
48
48
 
49
49
  private
@@ -2,17 +2,23 @@ require 'date'
2
2
 
3
3
  class LinuxAdmin
4
4
  class SubscriptionManager < RegistrationSystem
5
+ def run!(cmd, options = {})
6
+ super(cmd, options)
7
+ rescue CommandResultError => err
8
+ raise CredentialError.new(err.result) if err.result.error.downcase.include?("invalid username or password")
9
+ raise
10
+ end
5
11
 
6
12
  def validate_credentials(options)
7
13
  !!organizations(options)
8
14
  end
9
15
 
10
16
  def registered?
11
- run("subscription-manager identity", :return_exitstatus => true) == 0
17
+ run("subscription-manager identity").exit_status == 0
12
18
  end
13
19
 
14
20
  def refresh
15
- run("subscription-manager refresh")
21
+ run!("subscription-manager refresh")
16
22
  end
17
23
 
18
24
  def organizations(options)
@@ -23,8 +29,8 @@ class LinuxAdmin
23
29
  params.merge!(proxy_params(options))
24
30
  params["--serverurl="] = options[:server_url] if options[:server_url]
25
31
 
26
- output = run(cmd, :params => params, :return_output => true)
27
- parse_output(output).index_by {|i| i[:name]}
32
+ result = run!(cmd, :params => params)
33
+ parse_output(result.output).index_by {|i| i[:name]}
28
34
  end
29
35
 
30
36
  def register(options)
@@ -36,7 +42,7 @@ class LinuxAdmin
36
42
  params["--org="] = options[:org] if options[:server_url] && options[:org]
37
43
  params["--serverurl="] = options[:server_url] if options[:server_url]
38
44
 
39
- run(cmd, :params => params)
45
+ run!(cmd, :params => params)
40
46
  end
41
47
 
42
48
  def subscribe(options)
@@ -44,12 +50,12 @@ class LinuxAdmin
44
50
  pools = options[:pools].collect {|pool| ["--pool", pool]}
45
51
  params = proxy_params(options).to_a + pools
46
52
 
47
- run(cmd, :params => params)
53
+ run!(cmd, :params => params)
48
54
  end
49
55
 
50
56
  def available_subscriptions
51
57
  cmd = "subscription-manager list --all --available"
52
- output = run(cmd, :return_output => true)
58
+ output = run!(cmd).output
53
59
  parse_output(output).index_by {|i| i[:pool_id]}
54
60
  end
55
61
 
@@ -1,7 +1,7 @@
1
1
  class LinuxAdmin
2
2
  class Rpm < LinuxAdmin
3
3
  def self.list_installed
4
- out = run("rpm -qa --qf \"%{NAME} %{VERSION}-%{RELEASE}\n\"", :return_output => true)
4
+ out = run!("rpm -qa --qf \"%{NAME} %{VERSION}-%{RELEASE}\n\"").output
5
5
  out.split("\n").each_with_object({}) do |line, pkg_hash|
6
6
  name, ver = line.split(" ")
7
7
  pkg_hash[name] = ver
@@ -13,30 +13,29 @@ class LinuxAdmin
13
13
 
14
14
  def running?
15
15
  run(cmd(:service),
16
- :params => { nil => [id, "status"] },
17
- :return_exitstatus => true) == 0
16
+ :params => { nil => [id, "status"] }).exit_status == 0
18
17
  end
19
18
 
20
19
  def enable
21
- run(cmd(:systemctl),
20
+ run!(cmd(:systemctl),
22
21
  :params => { nil => ["enable", "#{id}.service"] })
23
22
  self
24
23
  end
25
24
 
26
25
  def disable
27
- run(cmd(:systemctl),
26
+ run!(cmd(:systemctl),
28
27
  :params => { nil => ["disable", "#{id}.service"] })
29
28
  self
30
29
  end
31
30
 
32
31
  def start
33
- run(cmd(:service),
32
+ run!(cmd(:service),
34
33
  :params => { nil => [id, "start"] })
35
34
  self
36
35
  end
37
36
 
38
37
  def stop
39
- run(cmd(:service),
38
+ run!(cmd(:service),
40
39
  :params => { nil => [id, "stop"] })
41
40
  self
42
41
  end
@@ -44,8 +43,7 @@ class LinuxAdmin
44
43
  def restart
45
44
  status =
46
45
  run(cmd(:service),
47
- :params => { nil => [id, "restart"] },
48
- :return_exitstatus => true)
46
+ :params => { nil => [id, "restart"] }).exit_status
49
47
 
50
48
  # attempt to manually stop/start if restart fails
51
49
  if status != 0
@@ -6,12 +6,12 @@
6
6
  class LinuxAdmin
7
7
  class System < LinuxAdmin
8
8
  def self.reboot!
9
- run(cmd(:shutdown),
9
+ run!(cmd(:shutdown),
10
10
  :params => { "-r" => "now" })
11
11
  end
12
12
 
13
13
  def self.shutdown!
14
- run(cmd(:shutdown),
14
+ run!(cmd(:shutdown),
15
15
  :params => { "-h" => "0" })
16
16
  end
17
17
  end
@@ -1,3 +1,3 @@
1
1
  class LinuxAdmin
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -31,13 +31,13 @@ class LinuxAdmin
31
31
  end
32
32
 
33
33
  def attach_to(lv)
34
- run(cmd(:lvextend),
34
+ run!(cmd(:lvextend),
35
35
  :params => [lv.name, self.name])
36
36
  self
37
37
  end
38
38
 
39
39
  def extend_with(pv)
40
- run(cmd(:vgextend),
40
+ run!(cmd(:vgextend),
41
41
  :params => [@name, pv.device_name])
42
42
  pv.volume_group = self
43
43
  self
@@ -45,7 +45,7 @@ class LinuxAdmin
45
45
 
46
46
  def self.create(name, pv)
47
47
  self.scan # initialize local volume groups
48
- run(cmd(:vgcreate),
48
+ run!(cmd(:vgcreate),
49
49
  :params => [name, pv.device_name])
50
50
  vg = VolumeGroup.new :name => name
51
51
  pv.volume_group = vg
@@ -57,9 +57,7 @@ class LinuxAdmin
57
57
  @vgs ||= begin
58
58
  vgs = []
59
59
 
60
- out = run(cmd(:vgdisplay),
61
- :return_output => true,
62
- :params => { '-c' => nil})
60
+ out = run!(cmd(:vgdisplay), :params => { '-c' => nil}).output
63
61
 
64
62
  out.each_line do |line|
65
63
  fields = line.split(':')