summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/transaction.rb6
-rw-r--r--lib/puppet/type.rb6
-rw-r--r--lib/puppet/type/package.rb86
-rwxr-xr-xlib/puppet/type/package/apt.rb40
-rwxr-xr-xlib/puppet/type/package/rpm.rb17
-rwxr-xr-xlib/puppet/type/package/yum.rb58
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