My OpenBSD installations cannot be managed well using Puppet.  There
are problems in few areas; this mail focuses on the package system.

The first problem is the coupling with the FreeBSD package system.
Despite some commonality, OpenBSD's present system is a rewrite by
Marc Espie.  Both systems are quite different and are developed
separately.  With present coupling, a change for OpenBSD side must
be tested not to break the FreeBSD side, and vice-versa.  Generally,
I think it's risky to put into the Puppet layer any assumptions
about their similarity.

Also, once decoupled, a pure-OpenBSD provider turned out pretty
small and clean.

Another problem is in flavor handling.  Puppet currently does not
replace a package if the installed flavor differs from the desired
one.  It's as if the parameter took effect at install time only.

Also, the output of ``puppet resource package'' lacks flavor name.
A flavor should be thought of as a name extension.  Dovecot in
sqlite flavor is non-trivially different from Dovecot in mysql
flavor.

The patch is against 2.6.8, but applies cleanly to 2.7.1, too.
I've tested on OpenBSD 4.9, and lightly on FreeBSD 8.1.

NB: I have less than 2 weeks of experience of Puppet codebase, and
of Ruby in general.  This provider adds functionality not present
in any other provider, so I may have integrated it not as cleanly
as an expert would.

Jacek

---
 provider/package.rb                          |    5 ++
 provider/package/freebsd.rb                  |    2 +-
 provider/package/{openbsd.rb => freebsd1.rb} |   11 ++--
 provider/package/pkg-openbsd.rb              |   91 ++++++++++++++++++++++++++
 type/package.rb                              |   17 ++++-
 5 files changed, 117 insertions(+), 9 deletions(-)
 rename provider/package/{openbsd.rb => freebsd1.rb} (88%)
 create mode 100644 provider/package/pkg-openbsd.rb

diff --git a/provider/package.rb b/provider/package.rb
index 2f5f675..b106d83 100644
--- a/provider/package.rb
+++ b/provider/package.rb
@@ -24,4 +24,9 @@ class Puppet::Provider::Package < Puppet::Provider
     end
     @property_hash.dup
   end
+
+  # Satisfy ``flavor'' property in non-OpenBSD package systems.
+  def flavor
+    return nil
+  end
 end
diff --git a/provider/package/freebsd.rb b/provider/package/freebsd.rb
index e10a20b..27ce246 100644
--- a/provider/package/freebsd.rb
+++ b/provider/package/freebsd.rb
@@ -1,4 +1,4 @@
-Puppet::Type.type(:package).provide :freebsd, :parent => :openbsd do
+Puppet::Type.type(:package).provide :freebsd, :parent => :freebsd1, :source => 
:freebsd do
   desc "The specific form of package management on FreeBSD.  This is an
     extremely quirky packaging system, in that it freely mixes between
     ports and packages.  Apparently all of the tools are written in Ruby,
diff --git a/provider/package/openbsd.rb b/provider/package/freebsd1.rb
similarity index 88%
rename from provider/package/openbsd.rb
rename to provider/package/freebsd1.rb
index bb07d89..d0d9a40 100644
--- a/provider/package/openbsd.rb
+++ b/provider/package/freebsd1.rb
@@ -1,13 +1,14 @@
 require 'puppet/provider/package'
 
-# Packaging on OpenBSD.  Doesn't work anywhere else that I know of.
-Puppet::Type.type(:package).provide :openbsd, :parent => 
Puppet::Provider::Package do
-  desc "OpenBSD's form of `pkg_add` support."
+# Old packaging support for OpenBSD.  Maintained because of FreeBSD's
+# package provider, which is a subclass.
+# XXX: need to clean this up.  Merge freebsd1.rb into freebsd.rb
+Puppet::Type.type(:package).provide :freebsd1, :parent => 
Puppet::Provider::Package, :source => :freebsd do
+  desc "FreeBSD `pkg_add` support."
 
   commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => 
"pkg_delete"
 
-  defaultfor :operatingsystem => :openbsd
-  confine :operatingsystem => :openbsd
+  confine :operatingsystem => :none
 
   has_feature :versionable
 
diff --git a/provider/package/pkg-openbsd.rb b/provider/package/pkg-openbsd.rb
new file mode 100644
index 0000000..42de68c
--- /dev/null
+++ b/provider/package/pkg-openbsd.rb
@@ -0,0 +1,91 @@
+# Author: Jacek Masiulaniec <jac...@dobremiasto.net>
+
+require 'puppet/provider/package'
+
+Puppet::Type.type(:package).provide :openbsd, :parent => 
Puppet::Provider::Package do
+  desc "Package management via `pkg`."
+  defaultfor :operatingsystem => :openbsd
+  confine :operatingsystem => :openbsd
+  has_feature :versionable
+  commands :pkg => 'pkg'
+
+
+  # Parses ``pkg info'' output.
+  def self.parse(package)
+    case package
+    when /^(\S+)-(\d\S*)-(\S+)$/
+      return {
+        :name     => $1,
+        :ensure   => $2,
+        :flavor   => $3,
+        :provider => self.name,
+      }
+    when /^(\S+)-(\d\S*)$/
+      return {
+        :name     => $1,
+        :ensure   => $2,
+        :flavor   => '',
+        :provider => self.name,
+      }
+    end
+    raise Puppet::Error, "Invalid package name: #{package}"
+  end
+
+
+  # Lists installed packages.
+  def self.instances
+    packages = []
+
+    execpipe('pkg info -q') do |process|
+      process.each do |line|
+        packages << new(parse(line.chomp))
+      end
+    end
+
+    packages
+  end
+
+
+  # Queries current package parameters.  By default, pkg info queries local
+  # database of installed packages, as well as remote repositories.  To 
restrict
+  # the query to local packages only, PKG_PATH environent variable is set to
+  # empty string.
+  def query
+    execpipe("PKG_PATH= pkg info -q -I #{@resource[:name]}") do |process|
+      if !(line = process.gets)
+        return nil
+      end
+      return parse(line.chomp)
+    end
+  end
+
+
+  # Adds new package.
+  def install
+    case @resource[:ensure]
+    when true, false, Symbol
+      version = ''
+    else
+      version = @resource[:ensure]
+    end
+    pkg ['add', "#{@resource[:name]}-#{version}-#{@resource[:flavor]}"]
+  end
+
+
+  # Deletes the package.
+  def uninstall
+    pkg ['delete', @resource[:name]]
+  end
+
+
+  # Gets the ``flavor'' property.
+  def flavor
+    @property_hash[:flavor]
+  end
+
+
+  # Sets the ``flavor'' property.
+  def flavor=(flavor)
+    pkg ['add', '-r', "#{@resource[:name]}--#{flavor}"]
+  end
+end
diff --git a/type/package.rb b/type/package.rb
index 1222a53..6ab12c8 100644
--- a/type/package.rb
+++ b/type/package.rb
@@ -286,9 +286,20 @@ module Puppet
       newvalues(:true, :false)
     end
 
-    newparam(:flavor) do
-      desc "Newer versions of OpenBSD support 'flavors', which are
-        further specifications for which type of package you want."
+    newproperty(:flavor) do
+      desc "OpenBSD supports flavors, which are further specifications for
+        which type of package you want."
+
+      count = 0
+      validate do |value|
+        if count > 1
+          raise ArgumentError, "multiple flavors specified"
+        end
+        if value =~ /\s/
+          raise ArgumentError, "%s is not a valid flavor" % value
+        end
+        count += 1
+      end
     end
 
     autorequire(:file) do
-- 
1.7.3.5

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to