diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/transaction.rb | 6 | ||||
-rw-r--r-- | lib/puppet/type.rb | 6 | ||||
-rw-r--r-- | lib/puppet/type/package.rb | 86 | ||||
-rwxr-xr-x | lib/puppet/type/package/apt.rb | 40 | ||||
-rwxr-xr-x | lib/puppet/type/package/rpm.rb | 17 | ||||
-rwxr-xr-x | lib/puppet/type/package/yum.rb | 58 |
6 files changed, 184 insertions, 29 deletions
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index a39ec55d1..57f43b17a 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -1,7 +1,3 @@ -#!/usr/local/bin/ruby -w - -# $Id$ - # the class that actually walks our object/state tree, collects the changes, # and performs them @@ -182,3 +178,5 @@ class Transaction end end #--------------------------------------------------------------- + +# $Id$ diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index a460e6024..f0ad6f0e7 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -1026,13 +1026,15 @@ class Type < Puppet::Element end # if all contained objects are in sync, then we're in sync - # FIXME I don't think this is used on the type instances any more + # FIXME I don't think this is used on the type instances any more, + # it's really only used for testing def insync? insync = true states.each { |state| unless state.insync? - Puppet.debug("%s is not in sync" % state) + Puppet.debug("%s is not in sync: %s vs %s" % + [state, state.is, state.should]) insync = false end } diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb index 6c8057576..098fff48e 100644 --- a/lib/puppet/type/package.rb +++ b/lib/puppet/type/package.rb @@ -7,6 +7,7 @@ require 'puppet/type/state' require 'puppet/type/package/dpkg.rb' require 'puppet/type/package/apt.rb' require 'puppet/type/package/rpm.rb' +require 'puppet/type/package/yum.rb' require 'puppet/type/package/sun.rb' module Puppet @@ -15,9 +16,40 @@ module Puppet class PackageInstalled < Puppet::State @name = :install - @doc = "What state the package should be in. - *true*/*false*/``version``" + @doc = "What state the package should be in. *true*/*false*/*latest*" + + # Override the parent method, because we've got all kinds of + # funky definitions of 'in sync'. + def insync? + Puppet.debug "is: %s" % @is + # Iterate across all of the should values, and see how they turn out. + @should.each { |should| + Puppet.debug "should: %s" % should + case should + when :installed + unless @is == :notinstalled + return true + end + when :latest + latest = @parent.latest + if @is == latest + return true + else + Puppet.warning "latest is %s" % latest + end + when :notinstalled + if @is == :notinstalled + return true + end + when @is + return true + end + } + + return false + end + # This retrieves the current state def retrieve unless defined? @is @parent.retrieve @@ -27,15 +59,22 @@ module Puppet def shouldprocess(value) # possible values are: true, false, and a version number case value - #when true, /^[0-9]/: - when true: - return value - when false: + when "latest": + unless @parent.respond_to?(:latest) + raise Puppet::Error, + "Package type %s does not support querying versions" % + @parent[:type] + end + return :latest + when true, :installed: + return :installed + when false, :notinstalled: return :notinstalled else - raise Puppet::Error.new( - "Invalid install value %s" % value - ) + # We allow them to set a should value however they want, + # but only specific package types will be able to use this + # value + return value end end @@ -43,18 +82,39 @@ module Puppet method = nil event = nil case @should[0] - when true: + when :installed: method = :install event = :package_installed when :notinstalled: method = :remove event = :package_removed + when :latest + if @is == :notinstalled + method = :install + event = :package_installed + else + method = :update + event = :package_updated + end else - raise Puppet::Error, "Invalid should value %s" % @should[0] + unless ! @parent.respond_to?(:versionable?) or @parent.versionable? + Puppet.warning value + raise Puppet::Error, + "Package type %s does not support specifying versions" % + @parent[:type] + else + method = :install + event = :package_installed + end end if @parent.respond_to?(method) + begin @parent.send(method) + rescue => detail + Puppet.err "Could not run %s: %s" % [method, detail.to_s] + raise + end else raise Puppet::Error, "Packages of type %s do not support %s" % [@parent[:type], method] @@ -76,6 +136,7 @@ module Puppet Puppet::PackagingType::APT, Puppet::PackagingType::DPKG, Puppet::PackagingType::RPM, + Puppet::PackagingType::Yum, Puppet::PackagingType::Sun ] @@ -168,7 +229,8 @@ module Puppet Puppet.notice "No support for gentoo yet" @default = nil when "debian": @default = :apt - when "redhat", "fedora": @default = :rpm + when "fedora": @default = :yum + when "redhat": @default = :rpm else Puppet.warning "Using rpm as default type for %s" % Facter["distro"].value diff --git a/lib/puppet/type/package/apt.rb b/lib/puppet/type/package/apt.rb index dd4e69d50..47887ec8a 100755 --- a/lib/puppet/type/package/apt.rb +++ b/lib/puppet/type/package/apt.rb @@ -6,9 +6,20 @@ module Puppet module APT include DPKG - # Install a package using 'apt-get'. + # Install a package using 'apt-get'. This function needs to support + # installing a specific version. def install - cmd = "apt-get install %s" % self.name + should = self.should(:install) + + str = self.name + case should + when true, false, Symbol + # pass + else + # Add the package version + str += "=%s" % should + end + cmd = "apt-get install %s" % str Puppet.info "Executing %s" % cmd.inspect output = %x{#{cmd} 2>&1} @@ -17,6 +28,31 @@ module Puppet raise Puppet::PackageError.new(output) end end + + # What's the latest package version available? + def latest + cmd = "apt-cache show %s" % self.name + output = %x{#{cmd} 2>&1} + + unless $? == 0 + raise Puppet::PackageError.new(output) + end + + if output =~ /Version: (.+)\n/ + return $1 + else + Puppet.debug "No version" + if Puppet[:debug] + print output + end + + return nil + end + end + + def update + self.install + end end end end diff --git a/lib/puppet/type/package/rpm.rb b/lib/puppet/type/package/rpm.rb index 3b195dcbc..ed88af507 100755 --- a/lib/puppet/type/package/rpm.rb +++ b/lib/puppet/type/package/rpm.rb @@ -8,29 +8,28 @@ module Puppet :description => "DESCRIPTION" } - cmd = "rpm -q --qf '%s\n'" % - %w{NAME VERSION DESCRIPTION}.collect { |str| - "%{#{str}}" - }.join(" ") + cmd = "rpm -q #{self.name} --qf '%s\n'" % + "%{NAME} %{VERSION}-%{RELEASE}" # list out all of the packages - str = %x{#{cmd} 2>/dev/null}.chomp + output = %x{#{cmd} 2>/dev/null}.chomp if $? != 0 return nil end - regex = %r{^(\S+)\s+(\S+)\s+(.+)} - fields = [:name, :install, :description] + regex = %r{^(\S+)\s+(\S+)} + #fields = [:name, :install, :description] + fields = [:name, :install] hash = {} - if match = regex.match(str) + if match = regex.match(output) fields.zip(match.captures) { |field,value| hash[field] = value } else raise Puppet::DevError, "Failed to match rpm output '%s'" % - str + output end return hash diff --git a/lib/puppet/type/package/yum.rb b/lib/puppet/type/package/yum.rb new file mode 100755 index 000000000..581f3f326 --- /dev/null +++ b/lib/puppet/type/package/yum.rb @@ -0,0 +1,58 @@ +module Puppet + module PackagingType + # A derivative of DPKG; this is how most people actually manage + # Debian boxes, and the only thing that differs is that it can + # install packages from remote sites. + module Yum + include RPM + + # Install a package using 'apt-get'. + def install + cmd = "yum -y install %s" % self.name + + Puppet.info "Executing %s" % cmd.inspect + output = %x{#{cmd} 2>&1} + + unless $? == 0 + raise Puppet::PackageError.new(output) + end + end + + # What's the latest package version available? + def latest + cmd = "yum list %s" % self.name + output = %x{#{cmd} 2>&1} + + unless $? == 0 + raise Puppet::PackageError.new(output) + end + + if output =~ /#{self.name}\S+\s+(\S+)\s/ + return $1 + else + Puppet.debug "No version" + if Puppet[:debug] + print output + end + + return nil + end + end + + def update + cmd = "yum -y update %s" % self.name + + Puppet.info "Executing %s" % cmd.inspect + output = %x{#{cmd} 2>&1} + + unless $? == 0 + raise Puppet::PackageError.new(output) + end + end + + def versionable? + false + end + end + end +end |