linux_admin 0.0.1 → 0.1.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/.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