summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Stahnke <stahnma@puppetlabs.com>2011-07-06 14:05:32 -0700
committerMichael Stahnke <stahnma@puppetlabs.com>2011-07-06 14:05:32 -0700
commit91acd8be41f3de25bca6b958ccc7698fb6ec9403 (patch)
tree418747ed81c9b1625617dee91e58a0bd110ec0e2
parent902c4147a2100c1f71d8493c526ae5275bab4cdc (diff)
parent6651b28d64d59eff6af0bb9722e151e4da88979e (diff)
downloadpuppet-91acd8be41f3de25bca6b958ccc7698fb6ec9403.tar.gz
puppet-91acd8be41f3de25bca6b958ccc7698fb6ec9403.tar.xz
puppet-91acd8be41f3de25bca6b958ccc7698fb6ec9403.zip
Merge branch 'master' into 2.7rc
-rw-r--r--lib/puppet/parser/functions/regsubst.rb26
-rw-r--r--lib/puppet/parser/functions/shellquote.rb26
-rw-r--r--lib/puppet/parser/functions/sprintf.rb26
-rw-r--r--lib/puppet/provider/package/pacman.rb94
-rw-r--r--spec/unit/provider/package/pacman_spec.rb237
5 files changed, 409 insertions, 0 deletions
diff --git a/lib/puppet/parser/functions/regsubst.rb b/lib/puppet/parser/functions/regsubst.rb
index b6bb5afcf..397d2b2ee 100644
--- a/lib/puppet/parser/functions/regsubst.rb
+++ b/lib/puppet/parser/functions/regsubst.rb
@@ -1,3 +1,29 @@
+# Copyright (C) 2009 Thomas Bellman
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THOMAS BELLMAN BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of Thomas Bellman shall
+# not be used in advertising or otherwise to promote the sale, use or
+# other dealings in this Software without prior written authorization
+# from Thomas Bellman.
+
module Puppet::Parser::Functions
newfunction(
diff --git a/lib/puppet/parser/functions/shellquote.rb b/lib/puppet/parser/functions/shellquote.rb
index 3ddb988f2..ee070c740 100644
--- a/lib/puppet/parser/functions/shellquote.rb
+++ b/lib/puppet/parser/functions/shellquote.rb
@@ -1,3 +1,29 @@
+# Copyright (C) 2009 Thomas Bellman
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THOMAS BELLMAN BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of Thomas Bellman shall
+# not be used in advertising or otherwise to promote the sale, use or
+# other dealings in this Software without prior written authorization
+# from Thomas Bellman.
+
module Puppet::Parser::Functions
Safe = 'a-zA-Z0-9@%_+=:,./-' # Safe unquoted
diff --git a/lib/puppet/parser/functions/sprintf.rb b/lib/puppet/parser/functions/sprintf.rb
index 5eb4a4f9d..118020412 100644
--- a/lib/puppet/parser/functions/sprintf.rb
+++ b/lib/puppet/parser/functions/sprintf.rb
@@ -1,3 +1,29 @@
+# Copyright (C) 2009 Thomas Bellman
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THOMAS BELLMAN BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of Thomas Bellman shall
+# not be used in advertising or otherwise to promote the sale, use or
+# other dealings in this Software without prior written authorization
+# from Thomas Bellman.
+
module Puppet::Parser::Functions
newfunction(
diff --git a/lib/puppet/provider/package/pacman.rb b/lib/puppet/provider/package/pacman.rb
new file mode 100644
index 000000000..5e05d147e
--- /dev/null
+++ b/lib/puppet/provider/package/pacman.rb
@@ -0,0 +1,94 @@
+require 'puppet/provider/package'
+
+Puppet::Type.type(:package).provide :pacman, :parent => Puppet::Provider::Package do
+ desc "Support for the Package Manager Utility (pacman) used in Archlinux."
+
+ commands :pacman => "/usr/bin/pacman"
+ defaultfor :operatingsystem => :archlinux
+ confine :operatingsystem => :archlinux
+ has_feature :upgradeable
+
+ # Install a package using 'pacman'.
+ # Installs quietly, without confirmation or progressbar, updates package
+ # list from servers defined in pacman.conf.
+ def install
+ pacman "--noconfirm", "--noprogressbar", "-Sy", @resource[:name]
+
+ unless self.query
+ raise Puppet::ExecutionFailure.new("Could not find package %s" % self.name)
+ end
+ end
+
+ def self.listcmd
+ [command(:pacman), " -Q"]
+ end
+
+ # Fetch the list of packages currently installed on the system.
+ def self.instances
+ packages = []
+ begin
+ execpipe(listcmd()) do |process|
+ # pacman -Q output is 'packagename version-rel'
+ regex = %r{^(\S+)\s(\S+)}
+ fields = [:name, :ensure]
+ hash = {}
+
+ process.each_line { |line|
+ if match = regex.match(line)
+ fields.zip(match.captures) { |field,value|
+ hash[field] = value
+ }
+
+ name = hash[:name]
+ hash[:provider] = self.name
+
+ packages << new(hash)
+ hash = {}
+ else
+ warning("Failed to match line %s" % line)
+ end
+ }
+ end
+ rescue Puppet::ExecutionFailure
+ return nil
+ end
+ packages
+ end
+
+ # Because Archlinux is a rolling release based distro, installing a package
+ # should always result in the newest release.
+ def update
+ # Install in pacman can be used for update, too
+ self.install
+ end
+
+ def latest
+ pacman "-Sy"
+ output = pacman "-Sp", "--print-format", "%v", @resource[:name]
+ output.chomp
+ end
+
+ # Querys the pacman master list for information about the package.
+ def query
+ begin
+ output = pacman("-Qi", @resource[:name])
+
+ if output =~ /Version.*:\s(.+)/
+ return { :ensure => $1 }
+ end
+ rescue Puppet::ExecutionFailure
+ return {
+ :ensure => :purged,
+ :status => 'missing',
+ :name => @resource[:name],
+ :error => 'ok',
+ }
+ end
+ nil
+ end
+
+ # Removes a package from the system.
+ def uninstall
+ pacman "--noconfirm", "--noprogressbar", "-R", @resource[:name]
+ end
+end
diff --git a/spec/unit/provider/package/pacman_spec.rb b/spec/unit/provider/package/pacman_spec.rb
new file mode 100644
index 000000000..679172621
--- /dev/null
+++ b/spec/unit/provider/package/pacman_spec.rb
@@ -0,0 +1,237 @@
+#!/usr/bin/env rspec
+require 'spec_helper'
+
+provider = Puppet::Type.type(:package).provider(:pacman)
+
+describe provider do
+ before do
+ provider.stubs(:command).with(:pacman).returns('/usr/bin/pacman')
+ @resource = stub 'resource'
+ @resource.stubs(:[]).returns("package")
+ @resource.stubs(:name).returns("name")
+ @provider = provider.new(@resource)
+ end
+
+ describe "when installing" do
+ before do
+ @provider.stubs(:query).returns({
+ :ensure => '1.0'
+ })
+ end
+
+ it "should call pacman" do
+ provider.
+ expects(:execute).
+ at_least_once.
+ with { |args|
+ args[0] == "/usr/bin/pacman"
+ }.
+ returns ""
+
+ @provider.install
+ end
+
+ it "should be quiet" do
+ provider.
+ expects(:execute).
+ with { |args|
+ args[1,2] == ["--noconfirm", "--noprogressbar"]
+ }.
+ returns("")
+
+ @provider.install
+ end
+
+ it "should install the right package" do
+ provider.
+ expects(:execute).
+ with { |args|
+ args[3,4] == ["-Sy", @resource[0]]
+ }.
+ returns("")
+
+ @provider.install
+ end
+
+ it "should raise an ExecutionFailure if the installation failed" do
+ provider.stubs(:execute).returns("")
+ @provider.expects(:query).returns(nil)
+
+ lambda { @provider.install }.should raise_exception(Puppet::ExecutionFailure)
+ end
+ end
+
+ describe "when updating" do
+ it "should call install" do
+ @provider.expects(:install).returns("install return value")
+ @provider.update.should == "install return value"
+ end
+ end
+
+ describe "when uninstalling" do
+ it "should call pacman" do
+ provider.
+ expects(:execute).
+ with { |args|
+ args[0] == "/usr/bin/pacman"
+ }.
+ returns ""
+
+ @provider.uninstall
+ end
+
+ it "should be quiet" do
+ provider.
+ expects(:execute).
+ with { |args|
+ args[1,2] == ["--noconfirm", "--noprogressbar"]
+ }.
+ returns("")
+
+ @provider.uninstall
+ end
+
+ it "should remove the right package" do
+ provider.
+ expects(:execute).
+ with { |args|
+ args[3,4] == ["-R", @resource[0]]
+ }.
+ returns("")
+
+ @provider.uninstall
+ end
+ end
+
+ describe "when querying" do
+ it "should query pacman" do
+ provider.
+ expects(:execute).
+ with(["/usr/bin/pacman", "-Qi", @resource[0]])
+ @provider.query
+ end
+
+ it "should return the version" do
+ query_output = <<EOF
+Name : package
+Version : 1.01.3-2
+URL : http://www.archlinux.org/pacman/
+Licenses : GPL
+Groups : base
+Provides : None
+Depends On : bash libarchive>=2.7.1 libfetch>=2.25 pacman-mirrorlist
+Optional Deps : fakeroot: for makepkg usage as normal user
+ curl: for rankmirrors usage
+Required By : None
+Conflicts With : None
+Replaces : None
+Installed Size : 2352.00 K
+Packager : Dan McGee <dan@archlinux.org>
+Architecture : i686
+Build Date : Sat 22 Jan 2011 03:56:41 PM EST
+Install Date : Thu 27 Jan 2011 06:45:49 AM EST
+Install Reason : Explicitly installed
+Install Script : Yes
+Description : A library-based package manager with dependency support
+EOF
+
+ provider.expects(:execute).returns(query_output)
+ @provider.query.should == {:ensure => "1.01.3-2"}
+ end
+
+ it "should return a nil if the package isn't found" do
+ provider.expects(:execute).returns("")
+ @provider.query.should be_nil
+ end
+
+ it "should return a hash indicating that the package is missing on error" do
+ provider.expects(:execute).raises(Puppet::ExecutionFailure.new("ERROR!"))
+ @provider.query.should == {
+ :ensure => :purged,
+ :status => 'missing',
+ :name => @resource[0],
+ :error => 'ok',
+ }
+ end
+ end
+
+ describe "when fetching a package list" do
+ it "should query pacman" do
+ provider.expects(:execpipe).with(["/usr/bin/pacman", ' -Q'])
+ provider.instances
+ end
+
+ it "should return installed packages with their versions" do
+ provider.expects(:execpipe).yields("package1 1.23-4\npackage2 2.00\n")
+ packages = provider.instances
+
+ packages.length.should == 2
+
+ packages[0].properties.should == {
+ :provider => :pacman,
+ :ensure => '1.23-4',
+ :name => 'package1'
+ }
+
+ packages[1].properties.should == {
+ :provider => :pacman,
+ :ensure => '2.00',
+ :name => 'package2'
+ }
+ end
+
+ it "should return nil on error" do
+ provider.expects(:execpipe).raises(Puppet::ExecutionFailure.new("ERROR!"))
+ provider.instances.should be_nil
+ end
+
+ it "should warn on invalid input" do
+ provider.expects(:execpipe).yields("blah")
+ provider.expects(:warning).with("Failed to match line blah")
+ provider.instances.should == []
+ end
+ end
+
+ describe "when determining the latest version" do
+ it "should refresh package list" do
+ refreshed = states('refreshed').starts_as('unrefreshed')
+ provider.
+ expects(:execute).
+ when(refreshed.is('unrefreshed')).
+ with(['/usr/bin/pacman', '-Sy']).
+ then(refreshed.is('refreshed'))
+
+ provider.
+ stubs(:execute).
+ when(refreshed.is('refreshed')).
+ returns("")
+
+ @provider.latest
+ end
+
+ it "should get query pacman for the latest version" do
+ refreshed = states('refreshed').starts_as('unrefreshed')
+ provider.
+ stubs(:execute).
+ when(refreshed.is('unrefreshed')).
+ then(refreshed.is('refreshed'))
+
+ provider.
+ expects(:execute).
+ when(refreshed.is('refreshed')).
+ with(['/usr/bin/pacman', '-Sp', '--print-format', '%v', @resource[0]]).
+ returns("")
+
+ @provider.latest
+ end
+
+ it "should return the version number from pacman" do
+ provider.
+ expects(:execute).
+ at_least_once().
+ returns("1.00.2-3\n")
+
+ @provider.latest.should == "1.00.2-3"
+ end
+ end
+end