linux_admin 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # LinuxAdmin
2
+ [![Gem Version](https://badge.fury.io/rb/linux_admin.png)](http://badge.fury.io/rb/linux_admin)
2
3
  [![Build Status](https://travis-ci.org/ManageIQ/linux_admin.png)](https://travis-ci.org/ManageIQ/linux_admin)
3
4
  [![Code Climate](https://codeclimate.com/github/ManageIQ/linux_admin.png)](https://codeclimate.com/github/ManageIQ/linux_admin)
4
5
  [![Coverage Status](https://coveralls.io/repos/ManageIQ/linux_admin/badge.png?branch=master)](https://coveralls.io/r/ManageIQ/linux_admin)
@@ -8,6 +9,9 @@ LinuxAdmin is a module to simplify management of linux systems.
8
9
  It should be a single place to manage various system level configurations,
9
10
  registration, updates, etc.
10
11
 
12
+ ## Supported Rubies
13
+ * MRI 1.9
14
+
11
15
  ## Installation
12
16
 
13
17
  Add this line to your application's Gemfile:
data/lib/linux_admin.rb CHANGED
@@ -1,10 +1,16 @@
1
+ require 'more_core_extensions/all'
2
+ require 'active_support/core_ext/string'
3
+
1
4
  require 'linux_admin/common'
2
5
  require 'linux_admin/rhn'
6
+ require 'linux_admin/rpm'
3
7
  require 'linux_admin/subscription_manager'
4
8
  require 'linux_admin/version'
5
9
  require 'linux_admin/yum'
6
10
 
7
- module LinuxAdmin
11
+ class LinuxAdmin
12
+ extend Common
13
+
8
14
  def self.registered?
9
15
  !!self.registration_type
10
16
  end
@@ -1,21 +1,94 @@
1
- module LinuxAdmin
1
+ require 'shellwords'
2
+
3
+ class LinuxAdmin
2
4
  module Common
3
- def self.run(cmd, options = {})
5
+ def write(file, content)
6
+ raise ArgumentError, "file and content can not be empty" if file.blank? || content.blank?
7
+ File.open(file, "w") do |f|
8
+ f.write(content)
9
+ end
10
+ end
11
+
12
+ def run(cmd, options = {})
13
+ params = options[:params] || options[:parameters]
14
+
4
15
  begin
5
- r, w = IO.pipe
6
- pid, status = Process.wait2(Kernel.spawn(cmd, :err => [:child, :out], :out => w))
7
- w.close
8
- if options[:return_output] && status.exitstatus == 0
9
- r.read
10
- elsif options[:return_exitstatus] || status.exitstatus == 0
11
- status.exitstatus
16
+ out = launch(build_cmd(cmd, params))
17
+
18
+ if options[:return_output] && exitstatus == 0
19
+ out
20
+ elsif options[:return_exitstatus] || exitstatus == 0
21
+ exitstatus
12
22
  else
13
- raise "Error: Exit Code #{status.exitstatus}"
23
+ raise "Error: Exit Code #{exitstatus}"
14
24
  end
15
25
  rescue
16
26
  return nil if options[:return_exitstatus]
17
27
  raise
28
+ ensure
29
+ self.exitstatus = nil
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def sanitize(params)
36
+ return {} if params.blank?
37
+ params.each_with_object({}) do |(k, v), h|
38
+ h[k] =
39
+ case v
40
+ when Array; v.collect {|s| s.shellescape}
41
+ when NilClass; v
42
+ else v.shellescape
43
+ end
44
+ end
45
+ end
46
+
47
+ def assemble_params(sanitized_params)
48
+ sanitized_params.collect do |pair|
49
+ pair_joiner = pair.first.try(:end_with?, "=") ? "" : " "
50
+ pair.flatten.compact.join(pair_joiner)
51
+ end.join(" ")
52
+ end
53
+
54
+ def build_cmd(cmd, params = nil)
55
+ return cmd if params.blank?
56
+ "#{cmd} #{assemble_params(sanitize(params))}"
57
+ end
58
+
59
+ # IO pipes have a maximum size of 64k before blocking,
60
+ # so we need to read and write synchronously.
61
+ # http://stackoverflow.com/questions/13829830/ruby-process-spawn-stdout-pipe-buffer-size-limit/13846146#13846146
62
+ THREAD_SYNC_KEY = "LinuxAdmin-exitstatus"
63
+
64
+ def launch(cmd)
65
+ pipe_r, pipe_w = IO.pipe
66
+ pid = Kernel.spawn(cmd, :err => [:child, :out], :out => pipe_w)
67
+ wait_for_process(pid, pipe_w)
68
+ wait_for_output(pipe_r)
69
+ end
70
+
71
+ def wait_for_process(pid, pipe_w)
72
+ self.exitstatus = :not_done
73
+ Thread.new(Thread.current) do |parent_thread|
74
+ _, status = Process.wait2(pid)
75
+ pipe_w.close
76
+ parent_thread[THREAD_SYNC_KEY] = status.exitstatus
18
77
  end
19
78
  end
79
+
80
+ def wait_for_output(pipe_r)
81
+ out = pipe_r.read
82
+ sleep(0.1) while exitstatus == :not_done
83
+ return out
84
+ end
85
+
86
+ def exitstatus
87
+ Thread.current[THREAD_SYNC_KEY]
88
+ end
89
+
90
+ def exitstatus=(value)
91
+ Thread.current[THREAD_SYNC_KEY] = value
92
+ end
20
93
  end
21
94
  end
@@ -1,7 +1,7 @@
1
1
  require 'nokogiri'
2
2
 
3
- module LinuxAdmin
4
- module Rhn
3
+ class LinuxAdmin
4
+ class Rhn < LinuxAdmin
5
5
  def self.systemid_file
6
6
  "/etc/sysconfig/rhn/systemid"
7
7
  end
@@ -0,0 +1,11 @@
1
+ class LinuxAdmin
2
+ class Rpm < LinuxAdmin
3
+ def self.list_installed
4
+ out = run("rpm -qa --qf \"%{NAME} %{VERSION}-%{RELEASE}\n\"", :return_output => true)
5
+ out.split("\n").each_with_object({}) do |line, pkg_hash|
6
+ name, ver = line.split(" ")
7
+ pkg_hash[name] = ver
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,28 +1,43 @@
1
1
  require 'date'
2
2
 
3
- module LinuxAdmin
4
- module SubscriptionManager
3
+ class LinuxAdmin
4
+ class SubscriptionManager < LinuxAdmin
5
5
  def self.registered?
6
- Common.run("subscription-manager identity", :return_exitstatus => true) == 0
6
+ run("subscription-manager identity", :return_exitstatus => true) == 0
7
7
  end
8
8
 
9
9
  def self.refresh
10
- Common.run("subscription-manager refresh")
10
+ run("subscription-manager refresh")
11
11
  end
12
12
 
13
13
  def self.register(options = {})
14
+ raise ArgumentError, "username and password are required" unless options[:username] && options[:password]
14
15
  cmd = "subscription-manager register"
15
- cmd << " --username=#{options[:username]} --password=#{options[:password]}" if options[:username] && options[:password]
16
- Common.run(cmd)
16
+
17
+ params = {}
18
+ if options[:username] && options[:password]
19
+ params["--username="] = options[:username]
20
+ params["--password="] = options[:password]
21
+ end
22
+ params["--org="] = options[:org] if options[:org] && options[:server_url]
23
+ params["--proxy="] = options[:proxy_address] if options[:proxy_address]
24
+ params["--proxyuser="] = options[:proxy_username] if options[:proxy_username]
25
+ params["--proxypassword="] = options[:proxy_password] if options[:proxy_password]
26
+ params["--serverurl="] = options[:server_url] if options[:server_url]
27
+
28
+ run(cmd, :params => params)
17
29
  end
18
30
 
19
31
  def self.subscribe(pool_id)
20
- Common.run("subscription-manager attach --pool #{pool_id}")
32
+ params = {"--pool" => pool_id}
33
+
34
+ run("subscription-manager attach", :params => params)
21
35
  end
22
36
 
23
37
  def self.available_subscriptions
24
- output = Common.run("subscription-manager list --all --available", :return_output => true)
25
- output.split("\n\n").each_with_object({}) do |subscription, subscriptions_hash|
38
+ out = run("subscription-manager list --all --available", :return_output => true)
39
+
40
+ out.split("\n\n").each_with_object({}) do |subscription, subscriptions_hash|
26
41
  hash = {}
27
42
  subscription.each_line do |line|
28
43
  # Strip the header lines if they exist
@@ -1,3 +1,3 @@
1
- module LinuxAdmin
2
- VERSION = "0.0.1"
1
+ class LinuxAdmin
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,7 +1,49 @@
1
- module LinuxAdmin
2
- module Yum
3
- def self.updates_available?
4
- exitstatus = Common.run("yum check-update", :return_exitstatus => true)
1
+ require 'fileutils'
2
+ require 'inifile'
3
+
4
+ class LinuxAdmin
5
+ class Yum < LinuxAdmin
6
+ def self.create_repo(path, options = {})
7
+ raise ArgumentError, "path is required" unless path
8
+ options = options.reverse_merge(:database => true, :unique_file_names => true)
9
+
10
+ FileUtils.mkdir_p(path)
11
+
12
+ cmd = "yum createrepo"
13
+ params = {nil => path}
14
+ params["--database"] = nil if options[:database]
15
+ params["--unique-md-filenames"] = nil if options[:unique_file_names]
16
+
17
+ run(cmd, :params => params)
18
+ end
19
+
20
+ def self.download_packages(path, packages, options = {})
21
+ raise ArgumentError, "path is required" unless path
22
+ raise ArgumentError, "packages are required" unless packages
23
+ options = options.reverse_merge(:mirror_type => :package)
24
+
25
+ FileUtils.mkdir_p(path)
26
+
27
+ cmd = case options[:mirror_type]
28
+ when :package; "yum repotrack"
29
+ else; raise ArgumentError, "mirror_type unsupported"
30
+ end
31
+ params = {"-p" => path}
32
+ params["-a"] = options[:arch] if options[:arch]
33
+ params[nil] = packages
34
+
35
+ run(cmd, :params => params)
36
+ end
37
+
38
+ def self.repo_settings
39
+ self.parse_repo_dir("/etc/yum.repos.d")
40
+ end
41
+
42
+ def self.updates_available?(*packages)
43
+ cmd = "yum check-update"
44
+ params = {nil => packages} unless packages.blank?
45
+
46
+ exitstatus = run(cmd, :params => params, :return_exitstatus => true)
5
47
  case exitstatus
6
48
  when 0; false
7
49
  when 100; true
@@ -9,8 +51,43 @@ module LinuxAdmin
9
51
  end
10
52
  end
11
53
 
12
- def self.update
13
- Common.run("yum -y update")
54
+ def self.update(*packages)
55
+ cmd = "yum -y update"
56
+ params = {nil => packages} unless packages.blank?
57
+
58
+ run(cmd, :params => params)
59
+ end
60
+
61
+ def self.version_available(*packages)
62
+ raise ArgumentError, "packages requires at least one package name" unless packages
63
+
64
+ cmd = "repoquery --qf=\"%{name} %{version}\""
65
+ params = {nil => packages}
66
+
67
+ out = run(cmd, :params => params, :return_output => true)
68
+
69
+ items = out.split("\n")
70
+ items.each_with_object({}) do |i, versions|
71
+ name, version = i.split(" ", 2)
72
+ versions[name.strip] = version.strip
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def self.parse_repo_dir(dir)
79
+ repo_files = Dir.glob(File.join(dir, '*.repo'))
80
+ repo_files.each_with_object({}) do |file, content|
81
+ content[file] = self.parse_repo_file(file)
82
+ end
83
+ end
84
+
85
+ def self.parse_repo_file(file)
86
+ int_keys = ["enabled", "cost", "gpgcheck", "sslverify", "metadata_expire"]
87
+ content = IniFile.load(file).to_h
88
+ content.each do |name, data|
89
+ int_keys.each { |k| data[k] = data[k].to_i if data.has_key?(k) }
90
+ end
14
91
  end
15
92
  end
16
93
  end
data/linux_admin.gemspec CHANGED
@@ -22,10 +22,13 @@ registration, updates, etc.
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
26
  spec.add_development_dependency "rake"
27
- spec.add_development_dependency "rspec", "~> 2.13"
27
+ spec.add_development_dependency "rspec", "~> 2.13"
28
28
  spec.add_development_dependency "coveralls"
29
29
 
30
+ spec.add_dependency "activesupport"
31
+ spec.add_dependency "inifile", "~> 2.0.2"
32
+ spec.add_dependency "more_core_extensions"
30
33
  spec.add_dependency "nokogiri"
31
- end
34
+ end
data/spec/common_spec.rb CHANGED
@@ -1,44 +1,95 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LinuxAdmin::Common do
4
+ before do
5
+ class TestClass
6
+ extend LinuxAdmin::Common
7
+ end
8
+ end
9
+
10
+ after do
11
+ Object.send(:remove_const, :TestClass)
12
+ end
13
+
14
+ let(:params) do
15
+ {
16
+ "--user" => "bob",
17
+ "--pass" => "P@$sw0^& |<>/-+*d%",
18
+ "--db" => nil,
19
+ "--desc=" => "Some Description",
20
+ nil => ["pkg1", "some pkg"]
21
+ }
22
+ end
23
+
24
+ subject { TestClass }
25
+
26
+ context ".write" do
27
+ it "no file no content" do
28
+ expect { subject.write("", "") }.to raise_error(ArgumentError)
29
+ end
30
+ end
31
+
4
32
  context ".run" do
33
+ context "with params" do
34
+ it "sanitizes crazy params" do
35
+ subject.should_receive(:launch).once.with("true --user bob --pass P@\\$sw0\\^\\&\\ \\|\\<\\>/-\\+\\*d\\% --db --desc=Some\\ Description pkg1 some\\ pkg")
36
+ subject.run("true", :params => params, :return_exitstatus => true)
37
+ end
38
+
39
+ it "as empty hash" do
40
+ subject.should_receive(:launch).once.with("true")
41
+ subject.run("true", :params => {}, :return_exitstatus => true)
42
+ end
43
+
44
+ it "as nil" do
45
+ subject.should_receive(:launch).once.with("true")
46
+ subject.run("true", :params => nil, :return_exitstatus => true)
47
+ end
48
+
49
+ it "won't modify caller params" do
50
+ orig_params = params.dup
51
+ subject.run("true", :params => params, :return_exitstatus => true)
52
+ expect(orig_params).to eq(params)
53
+ end
54
+ end
55
+
5
56
  it "command ok exit ok" do
6
- expect(described_class.run("true")).to be_true
57
+ expect(subject.run("true")).to be_true
7
58
  end
8
59
 
9
60
  it "command ok exit bad" do
10
- expect { described_class.run("false") }.to raise_error
61
+ expect { subject.run("false") }.to raise_error
11
62
  end
12
63
 
13
64
  it "command bad" do
14
- expect { described_class.run("XXXXX") }.to raise_error
65
+ expect { subject.run("XXXXX") }.to raise_error
15
66
  end
16
67
 
17
68
  context "with :return_exitstatus => true" do
18
69
  it "command ok exit ok" do
19
- expect(described_class.run("true", :return_exitstatus => true)).to eq(0)
70
+ expect(subject.run("true", :return_exitstatus => true)).to eq(0)
20
71
  end
21
72
 
22
73
  it "command ok exit bad" do
23
- expect(described_class.run("false", :return_exitstatus => true)).to eq(1)
74
+ expect(subject.run("false", :return_exitstatus => true)).to eq(1)
24
75
  end
25
76
 
26
77
  it "command bad" do
27
- expect(described_class.run("XXXXX", :return_exitstatus => true)).to be_nil
78
+ expect(subject.run("XXXXX", :return_exitstatus => true)).to be_nil
28
79
  end
29
80
  end
30
81
 
31
82
  context "with :return_output => true" do
32
83
  it "command ok exit ok" do
33
- expect(described_class.run("echo \"Hello World\"", :return_output => true)).to eq("Hello World\n")
84
+ expect(subject.run("echo \"Hello World\"", :return_output => true)).to eq("Hello World\n")
34
85
  end
35
86
 
36
87
  it "command ok exit bad" do
37
- expect { described_class.run("false", :return_output => true) }.to raise_error
88
+ expect { subject.run("false", :return_output => true) }.to raise_error
38
89
  end
39
90
 
40
91
  it "command bad" do
41
- expect { described_class.run("XXXXX", :return_output => true) }.to raise_error
92
+ expect { subject.run("XXXXX", :return_output => true) }.to raise_error
42
93
  end
43
94
  end
44
95
  end
@@ -0,0 +1,20 @@
1
+ ruby193-rubygem-some_really_long_name 1.0.7-1.el6
2
+ fipscheck-lib 1.2.0-7.el6
3
+ aic94xx-firmware 30-2.el6
4
+ latencytop-common 0.5-9.el6
5
+ uuid 1.6.1-10.el6
6
+ ConsoleKit 0.4.1-3.el6
7
+ cpuspeed 1.5-19.el6
8
+ mailcap 2.1.31-2.el6
9
+ freetds 0.82-7.1.el6cf
10
+ elinks 0.12-0.21.pre5.el6_3
11
+ abrt-cli 2.0.8-15.el6
12
+ libattr 2.4.44-7.el6
13
+ passwd 0.77-4.el6_2.2
14
+ vim-enhanced 7.2.411-1.8.el6
15
+ popt 1.13-7.el6
16
+ hesiod 3.1.0-19.el6
17
+ pinfo 0.6.9-12.el6
18
+ libpng 1.2.49-1.el6_2
19
+ libdhash 0.4.2-9.el6
20
+ zlib-devel 1.2.3-29.el6
@@ -0,0 +1,19 @@
1
+ [my-local-repo-a]
2
+ name = My Local Repo A
3
+ baseurl = https://mirror.example.com/a/content/os_ver
4
+ enabled = 0
5
+ gpgcheck = 1
6
+ gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-my-local-server
7
+ sslverify = 1
8
+ sslcacert = /etc/rhsm/ca/my-loacl-server.pem
9
+ sslclientkey = /etc/pki/entitlement/0123456789012345678-key.pem
10
+ sslclientcert = /etc/pki/entitlement/0123456789012345678.pem
11
+ metadata_expire = 86400
12
+
13
+ [my-local-repo-b]
14
+ name = My Local Repo B
15
+ baseurl = https://mirror.example.com/b/content/os_ver
16
+ enabled = 1
17
+ gpgcheck = 0
18
+ sslverify = 0
19
+ metadata_expire = 86400
@@ -0,0 +1,3 @@
1
+ curl 7.19.7
2
+ subscription-manager 1.1.23.1
3
+ wget 1.12
@@ -0,0 +1,9 @@
1
+ [my-local-repo-c]
2
+ name=My Local Repo c
3
+ baseurl=https://mirror.example.com/c/content/os_ver
4
+ enabled=0
5
+ cost=100
6
+ gpgcheck=1
7
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-my-local-server
8
+ sslverify=0
9
+ metadata_expire=1
data/spec/rpm_spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinuxAdmin::Rpm do
4
+ it ".list_installed" do
5
+ described_class.stub(:run => sample_output("rpm/cmd_output_for_list_installed"))
6
+ expect(described_class.list_installed).to eq({
7
+ "ruby193-rubygem-some_really_long_name" =>"1.0.7-1.el6",
8
+ "fipscheck-lib" =>"1.2.0-7.el6",
9
+ "aic94xx-firmware" =>"30-2.el6",
10
+ "latencytop-common" =>"0.5-9.el6",
11
+ "uuid" =>"1.6.1-10.el6",
12
+ "ConsoleKit" =>"0.4.1-3.el6",
13
+ "cpuspeed" =>"1.5-19.el6",
14
+ "mailcap" =>"2.1.31-2.el6",
15
+ "freetds" =>"0.82-7.1.el6cf",
16
+ "elinks" =>"0.12-0.21.pre5.el6_3",
17
+ "abrt-cli" =>"2.0.8-15.el6",
18
+ "libattr" =>"2.4.44-7.el6",
19
+ "passwd" =>"0.77-4.el6_2.2",
20
+ "vim-enhanced" =>"7.2.411-1.8.el6",
21
+ "popt" =>"1.13-7.el6",
22
+ "hesiod" =>"3.1.0-19.el6",
23
+ "pinfo" =>"0.6.9-12.el6",
24
+ "libpng" =>"1.2.49-1.el6_2",
25
+ "libdhash" =>"0.4.2-9.el6",
26
+ "zlib-devel" =>"1.2.3-29.el6",
27
+ })
28
+ end
29
+ end
@@ -3,40 +3,47 @@ require 'spec_helper'
3
3
  describe LinuxAdmin::SubscriptionManager do
4
4
  context ".registered?" do
5
5
  it "system with subscription-manager commands" do
6
- LinuxAdmin::Common.stub(:run => 0)
6
+ described_class.should_receive(:run).once.with("subscription-manager identity", {:return_exitstatus=>true}).and_return(0)
7
7
  expect(described_class.registered?).to be_true
8
8
  end
9
9
 
10
10
  it "system without subscription-manager commands" do
11
- LinuxAdmin::Common.stub(:run => 255)
11
+ described_class.should_receive(:run).once.with("subscription-manager identity", {:return_exitstatus=>true}).and_return(255)
12
12
  expect(described_class.registered?).to be_false
13
13
  end
14
14
  end
15
15
 
16
16
  it ".refresh" do
17
- LinuxAdmin::Common.should_receive(:run).once
17
+ described_class.should_receive(:run).once.with("subscription-manager refresh").and_return(0)
18
18
  described_class.refresh
19
19
  end
20
20
 
21
21
  context ".register" do
22
22
  it "no username" do
23
- LinuxAdmin::Common.should_receive(:run).once.with("subscription-manager register")
24
- described_class.register
23
+ expect { described_class.register }.to raise_error(ArgumentError)
25
24
  end
26
25
 
27
26
  it "with username and password" do
28
- LinuxAdmin::Common.should_receive(:run).once.with("subscription-manager register --username=SomeUser --password=SomePass")
29
- described_class.register(:username => "SomeUser", :password => "SomePass")
27
+ described_class.should_receive(:run).once.with("subscription-manager register", {:params=>{"--username="=>"SomeUser", "--password="=>"SomePass", "--org="=>"IT", "--proxy="=>"1.2.3.4", "--proxyuser="=>"ProxyUser", "--proxypassword="=>"ProxyPass", "--serverurl="=>"192.168.1.1"}}).and_return(0)
28
+ described_class.register(
29
+ :username => "SomeUser",
30
+ :password => "SomePass",
31
+ :org => "IT",
32
+ :proxy_address => "1.2.3.4",
33
+ :proxy_username => "ProxyUser",
34
+ :proxy_password => "ProxyPass",
35
+ :server_url => "192.168.1.1",
36
+ )
30
37
  end
31
38
  end
32
39
 
33
40
  it ".subscribe" do
34
- LinuxAdmin::Common.should_receive(:run).once
41
+ described_class.should_receive(:run).once
35
42
  described_class.subscribe(nil)
36
43
  end
37
44
 
38
45
  it ".available_subscriptions" do
39
- LinuxAdmin::Common.stub(:run => sample_output("subscription_manager/output_list_all_available"))
46
+ described_class.should_receive(:run).once.with("subscription-manager list --all --available", :return_output => true).and_return(sample_output("subscription_manager/output_list_all_available"))
40
47
  expect(described_class.available_subscriptions).to eq({
41
48
  "82c042fca983889b10178893f29b06e3" => {
42
49
  :subscription_name => "Example Subscription",
data/spec/yum_spec.rb CHANGED
@@ -1,30 +1,122 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LinuxAdmin::Yum do
4
+ before(:each) do
5
+ FileUtils.stub(:mkdir_p => true)
6
+ end
7
+
8
+ context ".create_repo" do
9
+ it "default arguments" do
10
+ described_class.should_receive(:run).once.with("yum createrepo", {:params=>{nil=>"some/path", "--database"=>nil, "--unique-md-filenames"=>nil}}).and_return true
11
+ expect(described_class.create_repo("some/path")).to be_true
12
+ end
13
+
14
+ it "bare create" do
15
+ described_class.should_receive(:run).once.with("yum createrepo", {:params=>{nil=>"some/path"}}).and_return true
16
+ expect(described_class.create_repo("some/path", :database => false, :unique_file_names => false)).to be_true
17
+ end
18
+ end
19
+
20
+ context ".download_packages" do
21
+ it "with valid input" do
22
+ described_class.should_receive(:run).once.with("yum repotrack", {:params=>{"-p"=>"some/path", nil=>"pkg_a pkg_b"}}).and_return true
23
+ expect(described_class.download_packages("some/path", "pkg_a pkg_b")).to be_true
24
+ end
25
+
26
+ it "without mirror type" do
27
+ expect { described_class.download_packages("some/path", "pkg_a pkg_b", :mirror_type => nil) }.to raise_error(ArgumentError)
28
+ end
29
+ end
30
+
31
+ it ".repo_settings" do
32
+ described_class.should_receive(:parse_repo_dir).once.with("/etc/yum.repos.d").and_return(true)
33
+ expect(described_class.repo_settings).to be_true
34
+ end
35
+
36
+ it ".parse_repo_dir" do
37
+ expect(described_class.parse_repo_dir(data_file_path("yum"))).to eq({
38
+ File.join(data_file_path("yum"), "first.repo") =>
39
+ { "my-local-repo-a" =>
40
+ { "name" =>"My Local Repo A",
41
+ "baseurl" =>"https://mirror.example.com/a/content/os_ver",
42
+ "enabled" =>0,
43
+ "gpgcheck" =>1,
44
+ "gpgkey" =>"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-my-local-server",
45
+ "sslverify" =>1,
46
+ "sslcacert" =>"/etc/rhsm/ca/my-loacl-server.pem",
47
+ "sslclientkey" =>"/etc/pki/entitlement/0123456789012345678-key.pem",
48
+ "sslclientcert" =>"/etc/pki/entitlement/0123456789012345678.pem",
49
+ "metadata_expire" =>86400},
50
+ "my-local-repo-b" =>
51
+ { "name" =>"My Local Repo B",
52
+ "baseurl" =>"https://mirror.example.com/b/content/os_ver",
53
+ "enabled" =>1,
54
+ "gpgcheck" =>0,
55
+ "sslverify" =>0,
56
+ "metadata_expire" =>86400}},
57
+ File.join(data_file_path("yum"), "second.repo") =>
58
+ { "my-local-repo-c" =>
59
+ { "name" =>"My Local Repo c",
60
+ "baseurl" =>"https://mirror.example.com/c/content/os_ver",
61
+ "enabled" =>0,
62
+ "cost" =>100,
63
+ "gpgcheck" =>1,
64
+ "gpgkey" =>"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-my-local-server",
65
+ "sslverify" =>0,
66
+ "metadata_expire" =>1}},})
67
+ end
68
+
4
69
  context ".updates_available?" do
70
+ it "check updates for a specific package" do
71
+ described_class.should_receive(:run).once.with("yum check-update", {:params=>{nil=>["abc"]}, :return_exitstatus=>true}).and_return(100)
72
+ expect(described_class.updates_available?("abc")).to be_true
73
+ end
74
+
5
75
  it "updates are available" do
6
- LinuxAdmin::Common.stub(:run => 100)
76
+ described_class.stub(:run => 100)
7
77
  expect(described_class.updates_available?).to be_true
8
78
  end
9
79
 
10
80
  it "updates not available" do
11
- LinuxAdmin::Common.stub(:run => 0)
81
+ described_class.stub(:run => 0)
12
82
  expect(described_class.updates_available?).to be_false
13
83
  end
14
84
 
15
85
  it "other exit code" do
16
- LinuxAdmin::Common.stub(:run => 255)
86
+ described_class.stub(:run => 255)
17
87
  expect { described_class.updates_available? }.to raise_error
18
88
  end
19
89
 
20
90
  it "other error" do
21
- LinuxAdmin::Common.stub(:run).and_raise(RuntimeError)
91
+ described_class.stub(:run).and_raise(RuntimeError)
22
92
  expect { described_class.updates_available? }.to raise_error
23
93
  end
24
94
  end
25
95
 
26
- it ".update" do
27
- LinuxAdmin::Common.should_receive(:run).once
28
- described_class.update
96
+ context ".update" do
97
+ it "no arguments" do
98
+ described_class.should_receive(:run).once.with("yum -y update", {:params=>nil}).and_return(0)
99
+ described_class.update
100
+ end
101
+
102
+ it "with arguments" do
103
+ described_class.should_receive(:run).once.with("yum -y update", {:params=>{nil=>["1 2", "3"]}}).and_return(0)
104
+ described_class.update("1 2", "3")
105
+ end
106
+ end
107
+
108
+ context ".version_available" do
109
+ it "no packages" do
110
+ expect { described_class.version_available }.to raise_error
111
+ end
112
+
113
+ it "with packages" do
114
+ described_class.should_receive(:run).once.with("repoquery --qf=\"%{name} %{version}\"", {:params=>{nil=>["curl"]}, :return_output=>true}).and_return(sample_output("yum/output_repoquery"))
115
+ expect(described_class.version_available("curl")).to eq({
116
+ "curl" => "7.19.7",
117
+ "subscription-manager" => "1.1.23.1",
118
+ "wget" => "1.12"
119
+ })
120
+ end
29
121
  end
30
122
  end
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.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-29 00:00:00.000000000 Z
12
+ date: 2013-05-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -75,6 +75,54 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: activesupport
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: inifile
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 2.0.2
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.0.2
110
+ - !ruby/object:Gem::Dependency
111
+ name: more_core_extensions
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
78
126
  - !ruby/object:Gem::Dependency
79
127
  name: nokogiri
80
128
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +155,7 @@ extensions: []
107
155
  extra_rdoc_files: []
108
156
  files:
109
157
  - .gitignore
158
+ - .travis.yml
110
159
  - Gemfile
111
160
  - LICENSE.txt
112
161
  - README.md
@@ -115,6 +164,7 @@ files:
115
164
  - lib/linux_admin.rb
116
165
  - lib/linux_admin/common.rb
117
166
  - lib/linux_admin/rhn.rb
167
+ - lib/linux_admin/rpm.rb
118
168
  - lib/linux_admin/subscription_manager.rb
119
169
  - lib/linux_admin/version.rb
120
170
  - lib/linux_admin/yum.rb
@@ -122,13 +172,17 @@ files:
122
172
  - spec/common_spec.rb
123
173
  - spec/data/rhn/systemid
124
174
  - spec/data/rhn/systemid.missing_system_id
175
+ - spec/data/rpm/cmd_output_for_list_installed
125
176
  - spec/data/subscription_manager/output_list_all_available
177
+ - spec/data/yum/first.repo
178
+ - spec/data/yum/output_repoquery
179
+ - spec/data/yum/second.repo
126
180
  - spec/linux_admin_spec.rb
127
181
  - spec/rhn_spec.rb
182
+ - spec/rpm_spec.rb
128
183
  - spec/spec_helper.rb
129
184
  - spec/subscription_manager_spec.rb
130
185
  - spec/yum_spec.rb
131
- - travis.yml
132
186
  homepage: http://github.com/ManageIQ/linux_admin
133
187
  licenses:
134
188
  - MIT
@@ -144,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
198
  version: '0'
145
199
  segments:
146
200
  - 0
147
- hash: 433652015813949549
201
+ hash: -3348050275566390969
148
202
  required_rubygems_version: !ruby/object:Gem::Requirement
149
203
  none: false
150
204
  requirements:
@@ -153,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
207
  version: '0'
154
208
  segments:
155
209
  - 0
156
- hash: 433652015813949549
210
+ hash: -3348050275566390969
157
211
  requirements: []
158
212
  rubyforge_project:
159
213
  rubygems_version: 1.8.24
@@ -164,9 +218,14 @@ test_files:
164
218
  - spec/common_spec.rb
165
219
  - spec/data/rhn/systemid
166
220
  - spec/data/rhn/systemid.missing_system_id
221
+ - spec/data/rpm/cmd_output_for_list_installed
167
222
  - spec/data/subscription_manager/output_list_all_available
223
+ - spec/data/yum/first.repo
224
+ - spec/data/yum/output_repoquery
225
+ - spec/data/yum/second.repo
168
226
  - spec/linux_admin_spec.rb
169
227
  - spec/rhn_spec.rb
228
+ - spec/rpm_spec.rb
170
229
  - spec/spec_helper.rb
171
230
  - spec/subscription_manager_spec.rb
172
231
  - spec/yum_spec.rb
data/travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - "1.8.7"
4
- - "1.9.2"
5
- - "1.9.3"
6
- - jruby-18mode # JRuby in 1.8 mode
7
- - jruby-19mode # JRuby in 1.9 mode
8
- - rbx-18mode
9
- - rbx-19mode