diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-07-03 20:06:32 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-07-03 20:06:32 +0000 |
| commit | e57c5131aee017bd015e9419b5a1ceeb306677a7 (patch) | |
| tree | 597984120e13b03bd96017afb84a050a728e17ea | |
| parent | 25cf31b00057d552fcffde568049e37655c31fbc (diff) | |
Adding Ruby Gem support to packaging
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1354 980ebf18-57e1-0310-9a29-db15c13687c0
| -rw-r--r-- | lib/puppet/type/package.rb | 48 | ||||
| -rwxr-xr-x | lib/puppet/type/package/gem.rb | 119 | ||||
| -rw-r--r-- | test/types/package.rb | 80 |
3 files changed, 203 insertions, 44 deletions
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb index ba0b307d1..58afe2c1c 100644 --- a/lib/puppet/type/package.rb +++ b/lib/puppet/type/package.rb @@ -60,6 +60,10 @@ module Puppet mod.module_eval(&block) + class << mod + include Puppet::Util + end + # It's at least conceivable that a module would not define this method # "module_function" makes the :list method private, so if the parent # method also called module_function, then it's already private @@ -575,50 +579,6 @@ module Puppet end end end # Puppet.type(:package) - - # this is how we retrieve packages - class PackageSource - attr_accessor :uri - attr_writer :retrieve - - @@sources = Hash.new(false) - - def PackageSource.get(file) - type = file.sub(%r{:.+},'') - source = nil - if source = @@sources[type] - return source.retrieve(file) - else - raise Puppet::Error, "Unknown package source: %s" % type - end - end - - def initialize(name) - if block_given? - yield self - end - - @@sources[name] = self - end - - def retrieve(path) - @retrieve.call(path) - end - - end - - PackageSource.new("file") { |obj| - obj.retrieve = proc { |path| - # this might not work for windows... - file = path.sub(%r{^file://},'') - - if FileTest.exists?(file) - return file - else - raise Puppet::Error, "File %s does not exist" % file - end - } - } end # $Id$ diff --git a/lib/puppet/type/package/gem.rb b/lib/puppet/type/package/gem.rb new file mode 100755 index 000000000..3763cf992 --- /dev/null +++ b/lib/puppet/type/package/gem.rb @@ -0,0 +1,119 @@ +module Puppet + Puppet.type(:package).newpkgtype(:gem) do + if gem = %x{which gem 2>/dev/null}.chomp and gem != "" + @@gem = gem + else + @@gem = nil + end + + def self.extended(mod) + unless @@gem + raise Puppet::Error, "The gem command is missing; gems unavailable" + end + end + + def gemlist(hash) + command = "#{@@gem} list " + + if hash[:local] + command += "--local " + else + command += "--remote " + end + + if hash[:justme] + command += self[:name] + end + begin + list = execute(command).split("\n\n").collect do |set| + if gemhash = gemsplit(set) + gemhash[:type] = :gem + gemhash[:ensure] = gemhash[:version][0] + gemhash + else + nil + end + end.reject { |p| p.nil? } + rescue ExecutionFailure => detail + raise Puppet::Error, "Could not list gems: %s" % detail + end + + if hash[:justme] + return list.shift + else + return list + end + end + + module_function :gemlist + + def gemsplit(desc) + case desc + when /^\*\*\*/: return nil + when /^(\S+)\s+\((.+)\)\n/ + name = $1 + version = $2.split(/,\s*/) + return { + :name => name, + :version => version + } + else + Puppet.warning "Could not match %s" % desc + nil + end + end + + module_function :gemsplit + + def install(useversion = true) + command = "#{@@gem} install " + if self[:version] and useversion + command += "-v %s " % self[:version] + end + if source = self[:source] + command += source + else + command += self[:name] + end + begin + execute(command) + rescue ExecutionFailure => detail + raise Puppet::Error, "Could not install %s: %s" % + [self[:name], detail] + end + end + + def latest + # This always gets the latest version available. + hash = gemlist(:justme => true) + + return hash[:version][0] + end + + def list(justme = false) + gemlist(:local => true).each do |hash| + Puppet::Type.type(:package).installedpkg(hash) + end + end + + def query + gemlist(:justme => true, :local => true) + end + + def uninstall + begin + # Remove everything, including the binaries. + execute("#{@@gem} uninstall -x -a #{self[:name]}") + rescue ExecutionFailure => detail + raise Puppet::Error, "Could not uninstall %s: %s" % + [self[:name], detail] + end + end + + def update + self.install(false) + end + end +end + +# $Id$ diff --git a/test/types/package.rb b/test/types/package.rb index e52d2384f..c6758885e 100644 --- a/test/types/package.rb +++ b/test/types/package.rb @@ -385,6 +385,86 @@ class TestPackages < Test::Unit::TestCase assert(FileTest.exists?("/tmp/pkgtesting/file"), "File did not get created") end end + + # Yay, gems. They're special because any OS can test them. + if %x{which gem 2>/dev/null}.chomp != "" + def test_list_gems + gems = nil + assert_nothing_raised { + gems = Puppet::Type.type(:package).pkgtype(:gem).list + } + + gems.each do |gem| + assert_equal(:gem, gem[:type], + "Type was not set correctly") + end + end + + def test_install_gems + gem = nil + name = "wxrubylayouts" + assert_nothing_raised { + gem = Puppet::Type.newpackage( + :name => name, + :version => "0.0.2", + :ensure => "installed", + :type => :gem + ) + } + + assert_nothing_raised { + gem.retrieve + } + + if gem.is(:ensure) == :installed + $stderr.puts "Cannot test gem installation; %s is already installed" % + name + end + + assert_events([:package_created], gem) + + assert_nothing_raised { + gem.retrieve + } + + assert_equal("0.0.2", gem.is(:ensure), + "Incorrect version was installed") + + latest = nil + assert_nothing_raised { + latest = gem.latest + } + + assert(latest != gem[:version], "Did not correctly find latest value") + + gem[:ensure] = :latest + assert_events([:package_changed], gem) + + gem.retrieve + + assert("0.0.2" != gem.is(:ensure), + "Package was not updated.") + + gem[:ensure] = :absent + + assert_events([:package_removed], gem) + end + + else + def test_nogems_nofailures + obj = nil + assert_nothing_raised do + Puppet::Type.newpackage( + :name => "yayness", + :type => "gem", + :ensure => "installed" + ) + end + + assert_nil(Puppet::Type.type(:package)["yayness"], + "Invalid gem package got created") + end + end end if ["Fedora", "RedHat", "CentOS"].include?(Facter["operatingsystem"].value) and FileTest.exists?("/home/luke/rpm/RPMS/i386/puppet-server-0.16.1-1.i386.rpm") |
