summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerdar Sutay <serdar@opscode.com>2014-05-08 15:22:55 -0700
committerSerdar Sutay <serdar@opscode.com>2014-05-08 15:22:55 -0700
commitca384a949df634ef1a2a1cd27df77c9fca02e097 (patch)
treecce279c2f5eb85058f08d1722ebb78f432839fe4
parent90389ed84ad01202bc15eaea0a60c2aab170e1e6 (diff)
parent2868830988498d13a157cb5f2fdbad0433d9f9b1 (diff)
downloadchef-ca384a949df634ef1a2a1cd27df77c9fca02e097.tar.gz
Merge pull request #1421 from opscode/sersut/CHEF-4637
CHEF-4637 - Add support for the new generation FreeBSD package manager
-rw-r--r--CHANGELOG.md1
-rw-r--r--CONTRIBUTIONS.md2
-rw-r--r--lib/chef/platform/provider_mapping.rb1
-rw-r--r--lib/chef/provider/package/freebsd.rb149
-rw-r--r--lib/chef/provider/package/freebsd/base.rb92
-rw-r--r--lib/chef/provider/package/freebsd/pkg.rb113
-rw-r--r--lib/chef/provider/package/freebsd/pkgng.rb80
-rw-r--r--lib/chef/provider/package/freebsd/port.rb70
-rw-r--r--lib/chef/providers.rb4
-rw-r--r--lib/chef/resource/freebsd_package.rb42
-rw-r--r--lib/chef/version/platform.rb2
-rw-r--r--spec/unit/provider/package/freebsd/pkg_spec.rb (renamed from spec/unit/provider/package/freebsd_spec.rb)51
-rw-r--r--spec/unit/provider/package/freebsd/pkgng_spec.rb155
-rw-r--r--spec/unit/provider/package/freebsd/port_spec.rb160
-rw-r--r--spec/unit/resource/freebsd_package_spec.rb74
-rw-r--r--spec/unit/version/platform_spec.rb2
16 files changed, 800 insertions, 198 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11f546f6e6..7d3afc44db 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
* `force_unlink` now only unlinks if the file already exists. (CHEF-5015)
* bootstrap no reports authentication failures. (CHEF-5161)
* `chef_gem` resource now uses omnibus gem binary. (CHEF-5092)
+* `freebsd_package` resource now uses the brand new "pkgng" package manager when available. (CHEF-4637)
## Last Release: 11.12.0 RC1 (03/31/2014)
* SIGTERM will once-more kill a non-daemonized chef-client (CHEF-5172)
diff --git a/CONTRIBUTIONS.md b/CONTRIBUTIONS.md
index f077f2f789..4b401521d2 100644
--- a/CONTRIBUTIONS.md
+++ b/CONTRIBUTIONS.md
@@ -14,3 +14,5 @@ Example Contribution:
* **viyh**: Made -E option to work with single lettered environments. (CHEF-3075)
* **JimmyMcCrory**: Added a 'knife node environment set' command. (CHEF-1910)
* **hongbin**: Made bootstrap report authentication exceptions. (CHEF-5161)
+* **liseki**: Made `freebsd_package` resource use the brand new "pkgng" package
+ manager when available.(CHEF-4637)
diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb
index 596e2ea8c6..4ebbde3486 100644
--- a/lib/chef/platform/provider_mapping.rb
+++ b/lib/chef/platform/provider_mapping.rb
@@ -57,7 +57,6 @@ class Chef
:freebsd => {
:default => {
:group => Chef::Provider::Group::Pw,
- :package => Chef::Provider::Package::Freebsd,
:service => Chef::Provider::Service::Freebsd,
:user => Chef::Provider::User::Pw,
:cron => Chef::Provider::Cron
diff --git a/lib/chef/provider/package/freebsd.rb b/lib/chef/provider/package/freebsd.rb
deleted file mode 100644
index f9cb5eb422..0000000000
--- a/lib/chef/provider/package/freebsd.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-#
-# Authors:: Bryan McLellan (btm@loftninjas.org)
-# Matthew Landauer (matthew@openaustralia.org)
-# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-require 'chef/provider/package'
-require 'chef/mixin/shell_out'
-require 'chef/resource/package'
-require 'chef/mixin/get_source_from_package'
-
-class Chef
- class Provider
- class Package
- class Freebsd < Chef::Provider::Package
- include Chef::Mixin::ShellOut
-
- include Chef::Mixin::GetSourceFromPackage
-
- def initialize(*args)
- super
- @current_resource = Chef::Resource::Package.new(@new_resource.name)
- end
-
- def current_installed_version
- pkg_info = shell_out!("pkg_info -E \"#{package_name}*\"", :env => nil, :returns => [0,1])
- pkg_info.stdout[/^#{Regexp.escape(package_name)}-(.+)/, 1]
- end
-
- def port_path
- case @new_resource.package_name
- # When the package name starts with a '/' treat it as the full path to the ports directory
- when /^\//
- @new_resource.package_name
- # Otherwise if the package name contains a '/' not at the start (like 'www/wordpress') treat as a relative
- # path from /usr/ports
- when /\//
- "/usr/ports/#{@new_resource.package_name}"
- # Otherwise look up the path to the ports directory using 'whereis'
- else
- whereis = shell_out!("whereis -s #{@new_resource.package_name}", :env => nil)
- unless path = whereis.stdout[/^#{Regexp.escape(@new_resource.package_name)}:\s+(.+)$/, 1]
- raise Chef::Exceptions::Package, "Could not find port with the name #{@new_resource.package_name}"
- end
- path
- end
- end
-
- def ports_makefile_variable_value(variable)
- make_v = shell_out!("make -V #{variable}", :cwd => port_path, :env => nil, :returns => [0,1])
- make_v.stdout.strip.split($\).first # $\ is the line separator, i.e., newline
- end
-
- def ports_candidate_version
- ports_makefile_variable_value("PORTVERSION")
- end
-
- def file_candidate_version_path
- Dir["#{@new_resource.source}/#{@current_resource.package_name}*"][-1].to_s
- end
-
- def file_candidate_version
- file_candidate_version_path.split(/-/).last.split(/.tbz/).first
- end
-
- def load_current_resource
- @current_resource.package_name(@new_resource.package_name)
-
- @current_resource.version(current_installed_version)
- Chef::Log.debug("#{@new_resource} current version is #{@current_resource.version}") if @current_resource.version
-
- case @new_resource.source
- when /^http/, /^ftp/
- @candidate_version = "0.0.0"
- when /^\//
- @candidate_version = file_candidate_version
- else
- @candidate_version = ports_candidate_version
- end
-
- Chef::Log.debug("#{@new_resource} ports candidate version is #{@candidate_version}") if @candidate_version
-
- @current_resource
- end
-
- def latest_link_name
- ports_makefile_variable_value("LATEST_LINK")
- end
-
- # The name of the package (without the version number) as understood by pkg_add and pkg_info
- def package_name
- if ::File.exist?("/usr/ports/Makefile")
- if ports_makefile_variable_value("PKGNAME") =~ /^(.+)-[^-]+$/
- $1
- else
- raise Chef::Exceptions::Package, "Unexpected form for PKGNAME variable in #{port_path}/Makefile"
- end
- else
- @new_resource.package_name
- end
- end
-
- def install_package(name, version)
- unless @current_resource.version
- case @new_resource.source
- when /^ports$/
- shell_out!("make -DBATCH install", :timeout => 1200, :env => nil, :cwd => port_path).status
- when /^http/, /^ftp/
- if @new_resource.source =~ /\/$/
- shell_out!("pkg_add -r #{package_name}", :env => { "PACKAGESITE" => @new_resource.source, 'LC_ALL' => nil }).status
- else
- shell_out!("pkg_add -r #{package_name}", :env => { "PACKAGEROOT" => @new_resource.source, 'LC_ALL' => nil }).status
- end
- Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
- when /^\//
- shell_out!("pkg_add #{file_candidate_version_path}", :env => { "PKG_PATH" => @new_resource.source , 'LC_ALL'=>nil}).status
- Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
- else
- shell_out!("pkg_add -r #{latest_link_name}", :env => nil).status
- end
- end
- end
-
- def remove_package(name, version)
- # a version is mandatory
- if version
- shell_out!("pkg_delete #{package_name}-#{version}", :env => nil).status
- else
- shell_out!("pkg_delete #{package_name}-#{@current_resource.version}", :env => nil).status
- end
- end
-
- end
- end
- end
-end
diff --git a/lib/chef/provider/package/freebsd/base.rb b/lib/chef/provider/package/freebsd/base.rb
new file mode 100644
index 0000000000..24f79484f0
--- /dev/null
+++ b/lib/chef/provider/package/freebsd/base.rb
@@ -0,0 +1,92 @@
+#
+# Authors:: Bryan McLellan (btm@loftninjas.org)
+# Matthew Landauer (matthew@openaustralia.org)
+# Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/resource/package'
+require 'chef/provider/package'
+require 'chef/mixin/shell_out'
+require 'chef/mixin/get_source_from_package'
+
+class Chef
+ class Provider
+ class Package
+ module Freebsd
+
+ module PortsHelper
+ def supports_ports?
+ ::File.exist?("/usr/ports/Makefile")
+ end
+
+ def port_dir(port)
+ case port
+
+ # When the package name starts with a '/' treat it as the full path to the ports directory.
+ when /^\//
+ port
+
+ # Otherwise if the package name contains a '/' not at the start (like 'www/wordpress') treat
+ # as a relative path from /usr/ports.
+ when /\//
+ "/usr/ports/#{port}"
+
+ # Otherwise look up the path to the ports directory using 'whereis'
+ else
+ whereis = shell_out!("whereis -s #{port}", :env => nil)
+ unless _path = whereis.stdout[/^#{Regexp.escape(port)}:\s+(.+)$/, 1]
+ raise Chef::Exceptions::Package, "Could not find port with the name #{port}"
+ end
+ _path
+ end
+ end
+
+ def makefile_variable_value(variable, dir = nil)
+ options = dir ? { :cwd => dir } : {}
+ make_v = shell_out!("make -V #{variable}", options.merge!(:env => nil, :returns => [0,1]))
+ make_v.exitstatus.zero? ? make_v.stdout.strip.split($\).first : nil # $\ is the line separator, i.e. newline.
+ end
+ end
+
+
+ class Base < Chef::Provider::Package
+ include Chef::Mixin::ShellOut
+ include Chef::Mixin::GetSourceFromPackage
+
+ def initialize(*args)
+ super
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
+ end
+
+ def load_current_resource
+ @current_resource.package_name(@new_resource.package_name)
+
+ @current_resource.version(current_installed_version)
+ Chef::Log.debug("#{@new_resource} current version is #{@current_resource.version}") if @current_resource.version
+
+ @candidate_version = candidate_version
+ Chef::Log.debug("#{@new_resource} candidate version is #{@candidate_version}") if @candidate_version
+
+ @current_resource
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/freebsd/pkg.rb b/lib/chef/provider/package/freebsd/pkg.rb
new file mode 100644
index 0000000000..c757d26fe5
--- /dev/null
+++ b/lib/chef/provider/package/freebsd/pkg.rb
@@ -0,0 +1,113 @@
+#
+# Authors:: Bryan McLellan (btm@loftninjas.org)
+# Matthew Landauer (matthew@openaustralia.org)
+# Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/package/freebsd/base'
+
+class Chef
+ class Provider
+ class Package
+ module Freebsd
+ class Pkg < Base
+ include PortsHelper
+
+ def install_package(name, version)
+ unless @current_resource.version
+ case @new_resource.source
+ when /^http/, /^ftp/
+ if @new_resource.source =~ /\/$/
+ shell_out!("pkg_add -r #{package_name}", :env => { "PACKAGESITE" => @new_resource.source, 'LC_ALL' => nil }).status
+ else
+ shell_out!("pkg_add -r #{package_name}", :env => { "PACKAGEROOT" => @new_resource.source, 'LC_ALL' => nil }).status
+ end
+ Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
+
+ when /^\//
+ shell_out!("pkg_add #{file_candidate_version_path}", :env => { "PKG_PATH" => @new_resource.source , 'LC_ALL'=>nil}).status
+ Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
+
+ else
+ shell_out!("pkg_add -r #{latest_link_name}", :env => nil).status
+ end
+ end
+ end
+
+ def remove_package(name, version)
+ shell_out!("pkg_delete #{package_name}-#{version || @current_resource.version}", :env => nil).status
+ end
+
+ # The name of the package (without the version number) as understood by pkg_add and pkg_info.
+ def package_name
+ if supports_ports?
+ if makefile_variable_value("PKGNAME", port_path) =~ /^(.+)-[^-]+$/
+ $1
+ else
+ raise Chef::Exceptions::Package, "Unexpected form for PKGNAME variable in #{port_path}/Makefile"
+ end
+ else
+ @new_resource.package_name
+ end
+ end
+
+ def latest_link_name
+ makefile_variable_value("LATEST_LINK", port_path)
+ end
+
+ def current_installed_version
+ pkg_info = shell_out!("pkg_info -E \"#{package_name}*\"", :env => nil, :returns => [0,1])
+ pkg_info.stdout[/^#{Regexp.escape(package_name)}-(.+)/, 1]
+ end
+
+ def candidate_version
+ case @new_resource.source
+ when /^http/, /^ftp/
+ repo_candidate_version
+ when /^\//
+ file_candidate_version
+ else
+ ports_candidate_version
+ end
+ end
+
+ def file_candidate_version_path
+ Dir["#{@new_resource.source}/#{@current_resource.package_name}*"][-1].to_s
+ end
+
+ def file_candidate_version
+ file_candidate_version_path.split(/-/).last.split(/.tbz/).first
+ end
+
+ def repo_candidate_version
+ "0.0.0"
+ end
+
+ def ports_candidate_version
+ makefile_variable_value("PORTVERSION", port_path)
+ end
+
+ def port_path
+ port_dir @new_resource.package_name
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/freebsd/pkgng.rb b/lib/chef/provider/package/freebsd/pkgng.rb
new file mode 100644
index 0000000000..da531facc1
--- /dev/null
+++ b/lib/chef/provider/package/freebsd/pkgng.rb
@@ -0,0 +1,80 @@
+#
+# Authors:: Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/package/freebsd/base'
+
+class Chef
+ class Provider
+ class Package
+ module Freebsd
+ class Pkgng < Base
+
+ def install_package(name, version)
+ unless @current_resource.version
+ case @new_resource.source
+ when /^(http|ftp|\/)/
+ shell_out!("pkg add#{expand_options(@new_resource.options)} #{@new_resource.source}", :env => { 'LC_ALL' => nil }).status
+ Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
+
+ else
+ shell_out!("pkg install -y#{expand_options(@new_resource.options)} #{name}", :env => { 'LC_ALL' => nil }).status
+ end
+ end
+ end
+
+ def remove_package(name, version)
+ options = @new_resource.options && @new_resource.options.sub(repo_regex, '')
+ options && !options.empty? || options = nil
+ shell_out!("pkg delete -y#{expand_options(options)} #{name}#{version ? '-' + version : ''}", :env => nil).status
+ end
+
+ def current_installed_version
+ pkg_info = shell_out!("pkg info \"#{@new_resource.package_name}\"", :env => nil, :returns => [0,70])
+ pkg_info.stdout[/^#{Regexp.escape(@new_resource.package_name)}-(.+)/, 1]
+ end
+
+ def candidate_version
+ @new_resource.source ? file_candidate_version : repo_candidate_version
+ end
+
+
+
+ private
+
+ def file_candidate_version
+ @new_resource.source[/#{Regexp.escape(@new_resource.package_name)}-(.+)\.txz/, 1]
+ end
+
+ def repo_candidate_version
+ if @new_resource.options && @new_resource.options.match(repo_regex)
+ options = $1
+ end
+
+ pkg_query = shell_out!("pkg rquery#{expand_options(options)} '%v' #{@new_resource.package_name}", :env => nil)
+ pkg_query.exitstatus.zero? ? pkg_query.stdout.strip.split(/\n/).last : nil
+ end
+
+ def repo_regex
+ /(-r\s?\S+)\b/
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/freebsd/port.rb b/lib/chef/provider/package/freebsd/port.rb
new file mode 100644
index 0000000000..6f4471a6f7
--- /dev/null
+++ b/lib/chef/provider/package/freebsd/port.rb
@@ -0,0 +1,70 @@
+#
+# Authors:: Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/package/freebsd/base'
+
+class Chef
+ class Provider
+ class Package
+ module Freebsd
+ class Port < Base
+ include PortsHelper
+
+ def install_package(name, version)
+ shell_out!("make -DBATCH install clean", :timeout => 1800, :env => nil, :cwd => port_dir).status
+ end
+
+ def remove_package(name, version)
+ shell_out!("make deinstall", :timeout => 300, :env => nil, :cwd => port_dir).status
+ end
+
+ def current_installed_version
+ pkg_info = if supports_pkgng?
+ shell_out!("pkg info \"#{@new_resource.package_name}\"", :env => nil, :returns => [0,70])
+ else
+ shell_out!("pkg_info -E \"#{@new_resource.package_name}*\"", :env => nil, :returns => [0,1])
+ end
+ pkg_info.stdout[/^#{Regexp.escape(@new_resource.package_name)}-(.+)/, 1]
+ end
+
+ def candidate_version
+ if supports_ports?
+ makefile_variable_value("PORTVERSION", port_dir)
+ else
+ raise Chef::Exceptions::Package, "Ports collection could not be found"
+ end
+ end
+
+ def port_dir
+ super(@new_resource.package_name)
+ end
+
+
+
+ private
+
+ def supports_pkgng?
+ with_pkgng = makefile_variable_value('WITH_PKGNG')
+ with_pkgng && with_pkgng =~ /yes/i
+ end
+
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index 6cfd12827a..d6e70c1d4e 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -55,7 +55,9 @@ require 'chef/provider/env/windows'
require 'chef/provider/package/apt'
require 'chef/provider/package/dpkg'
require 'chef/provider/package/easy_install'
-require 'chef/provider/package/freebsd'
+require 'chef/provider/package/freebsd/port'
+require 'chef/provider/package/freebsd/pkg'
+require 'chef/provider/package/freebsd/pkgng'
require 'chef/provider/package/ips'
require 'chef/provider/package/macports'
require 'chef/provider/package/pacman'
diff --git a/lib/chef/resource/freebsd_package.rb b/lib/chef/resource/freebsd_package.rb
index 94286eae18..c7a8d44181 100644
--- a/lib/chef/resource/freebsd_package.rb
+++ b/lib/chef/resource/freebsd_package.rb
@@ -1,6 +1,8 @@
#
-# Author:: AJ Christensen (<aj@opscode.com>)
+# Authors:: AJ Christensen (<aj@opscode.com>)
+# Richard Manyanza (<liseki@nyikacraftsmen.com>)
# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Copyright:: Copyright (c) 2014 Richard Manyanza.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,16 +19,50 @@
#
require 'chef/resource/package'
-require 'chef/provider/package/freebsd'
+require 'chef/provider/package/freebsd/port'
+require 'chef/provider/package/freebsd/pkg'
+require 'chef/provider/package/freebsd/pkgng'
+require 'chef/mixin/shell_out'
class Chef
class Resource
class FreebsdPackage < Chef::Resource::Package
+ include Chef::Mixin::ShellOut
+
+ provides :package, :on_platforms => ["freebsd"]
+
def initialize(name, run_context=nil)
super
@resource_name = :freebsd_package
- @provider = Chef::Provider::Package::Freebsd
+ end
+
+ def after_created
+ assign_provider
+ end
+
+
+
+ private
+
+ def assign_provider
+ @provider = if @source.to_s =~ /^ports$/i
+ Chef::Provider::Package::Freebsd::Port
+ elsif ships_with_pkgng? || supports_pkgng?
+ Chef::Provider::Package::Freebsd::Pkgng
+ else
+ Chef::Provider::Package::Freebsd::Pkg
+ end
+ end
+
+ def ships_with_pkgng?
+ # It was not until __FreeBSD_version 1000017 that pkgng became
+ # the default binary package manager. See '/usr/ports/Mk/bsd.port.mk'.
+ node[:os_version].to_i >= 1000017
+ end
+
+ def supports_pkgng?
+ !!shell_out!("make -V WITH_PKGNG", :env => nil).stdout.match(/yes/i)
end
end
diff --git a/lib/chef/version/platform.rb b/lib/chef/version/platform.rb
index 2921341cd2..81e7614646 100644
--- a/lib/chef/version/platform.rb
+++ b/lib/chef/version/platform.rb
@@ -31,6 +31,8 @@ class Chef
[ $1.to_i, $2.to_i, 0 ]
when /^(\d+)$/
[ $1.to_i, 0, 0 ]
+ when /^(\d+).(\d+)-[a-z]+\d?(-p(\d+))?$/i # Match FreeBSD
+ [ $1.to_i, $2.to_i, ($4 ? $4.to_i : 0)]
else
msg = "'#{str.to_s}' does not match 'x.y.z', 'x.y' or 'x'"
raise Chef::Exceptions::InvalidPlatformVersion.new( msg )
diff --git a/spec/unit/provider/package/freebsd_spec.rb b/spec/unit/provider/package/freebsd/pkg_spec.rb
index 962f9c23d1..9b2493a4c5 100644
--- a/spec/unit/provider/package/freebsd_spec.rb
+++ b/spec/unit/provider/package/freebsd/pkg_spec.rb
@@ -20,7 +20,7 @@
require 'spec_helper'
require 'ostruct'
-describe Chef::Provider::Package::Freebsd, "load_current_resource" do
+describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do
before(:each) do
@node = Chef::Node.new
@events = Chef::EventDispatch::Dispatcher.new
@@ -28,7 +28,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@new_resource = Chef::Resource::Package.new("zsh")
@current_resource = Chef::Resource::Package.new("zsh")
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
::File.stub(:exist?).with('/usr/ports/Makefile').and_return(false)
end
@@ -39,7 +39,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
end
it "should create a current resource with the name of the new_resource" do
- current_resource = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context).current_resource
+ current_resource = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context).current_resource
current_resource.name.should == "zsh"
end
@@ -66,7 +66,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
before do
#@new_resource = Chef::Resource::Package.new("zsh")
- #@provider = Chef::Provider::Package::Freebsd.new(@node, @new_resource)
+ #@provider = Chef::Provider::Package::Freebsd::Pkg.new(@node, @new_resource)
#@status = double("Status", :exitstatus => 0)
#@stdin = double("STDIN", :null_object => true)
@@ -101,7 +101,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
# Not happy with the form of these tests as they are far too closely tied to the implementation and so very fragile.
it "should return the ports candidate version when given a valid port path" do
@provider.stub(:port_path).and_return("/usr/ports/shells/zsh")
- make_v = OpenStruct.new(:stdout => "4.3.6\n")
+ make_v = OpenStruct.new(:stdout => "4.3.6\n", :exitstatus => 0)
@provider.should_receive(:shell_out!).with("make -V PORTVERSION", {:cwd=>"/usr/ports/shells/zsh", :returns=>[0, 1], :env=>nil}).and_return(make_v)
@provider.ports_candidate_version.should == "4.3.6"
end
@@ -109,14 +109,14 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
it "should figure out the package name when we have ports" do
::File.stub(:exist?).with('/usr/ports/Makefile').and_return(true)
@provider.stub(:port_path).and_return("/usr/ports/shells/zsh")
- make_v = OpenStruct.new(:stdout => "zsh-4.3.6_7\n")
+ make_v = OpenStruct.new(:stdout => "zsh-4.3.6_7\n", :exitstatus => 0)
@provider.should_receive(:shell_out!).with("make -V PKGNAME", {:cwd=>"/usr/ports/shells/zsh", :env=>nil, :returns=>[0, 1]}).and_return(make_v)
#@provider.should_receive(:ports_makefile_variable_value).with("PKGNAME").and_return("zsh-4.3.6_7")
@provider.package_name.should == "zsh"
end
end
- describe Chef::Provider::Package::Freebsd, "install_package" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "install_package" do
before(:each) do
@cmd_result = OpenStruct.new(:status => true)
@@ -130,21 +130,14 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@provider.should_receive(:shell_out!).with("pkg_add -r zsh", :env => nil).and_return(@cmd_result)
@provider.install_package("zsh", "4.3.6_7")
end
-
- it "should run make install when installing from ports" do
- @new_resource.stub(:source).and_return("ports")
- @provider.should_not_receive(:shell_out!).with("make -DBATCH -f /usr/ports/shells/zsh/Makefile install", :timeout => 1200, :env=>nil)
- @provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@cmd_result)
- @provider.install_package("zsh", "4.3.6_7")
- end
end
- describe Chef::Provider::Package::Freebsd, "port path" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "port path" do
before do
#@node = Chef::Node.new
@new_resource = Chef::Resource::Package.new("zsh")
@new_resource.cookbook_name = "adventureclub"
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
end
it "should figure out the port path from the package_name using whereis" do
@@ -155,7 +148,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
it "should use the package_name as the port path when it starts with /" do
new_resource = Chef::Resource::Package.new("/usr/ports/www/wordpress")
- provider = Chef::Provider::Package::Freebsd.new(new_resource, @run_context)
+ provider = Chef::Provider::Package::Freebsd::Pkg.new(new_resource, @run_context)
provider.should_not_receive(:popen4)
provider.port_path.should == "/usr/ports/www/wordpress"
end
@@ -165,17 +158,17 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
# :package_name => "www/wordpress",
# :cookbook_name => "xenoparadox")
new_resource = Chef::Resource::Package.new("www/wordpress")
- provider = Chef::Provider::Package::Freebsd.new(new_resource, @run_context)
+ provider = Chef::Provider::Package::Freebsd::Pkg.new(new_resource, @run_context)
provider.should_not_receive(:popen4)
provider.port_path.should == "/usr/ports/www/wordpress"
end
end
- describe Chef::Provider::Package::Freebsd, "ruby-iconv (package with a dash in the name)" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "ruby-iconv (package with a dash in the name)" do
before(:each) do
@new_resource = Chef::Resource::Package.new("ruby-iconv")
@current_resource = Chef::Resource::Package.new("ruby-iconv")
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
@provider.stub(:port_path).and_return("/usr/ports/converters/ruby-iconv")
@provider.stub(:package_name).and_return("ruby18-iconv")
@@ -188,15 +181,9 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@provider.should_receive(:shell_out!).with("pkg_add -r ruby18-iconv", :env => nil).and_return(@install_result)
@provider.install_package("ruby-iconv", "1.0")
end
-
- it "should run make install when installing from ports" do
- @new_resource.stub(:source).and_return("ports")
- @provider.should_receive(:shell_out!).with("make -DBATCH install", :timeout => 1200, :env=>nil, :cwd => @provider.port_path).and_return(@install_result)
- @provider.install_package("ruby-iconv", "1.0")
- end
end
- describe Chef::Provider::Package::Freebsd, "remove_package" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "remove_package" do
before(:each) do
@pkg_delete = OpenStruct.new(:status => true)
@new_resource.version "4.3.6_7"
@@ -216,11 +203,11 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
# version of a package is currently installed and to get the port_path.
# Example package name: bonnie++
- describe Chef::Provider::Package::Freebsd, "bonnie++ (package with a plus in the name :: CHEF-4371)" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "bonnie++ (package with a plus in the name :: CHEF-4371)" do
before(:each) do
@new_resource = Chef::Resource::Package.new("bonnie++")
@current_resource = Chef::Resource::Package.new("bonnie++")
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
end
@@ -256,11 +243,11 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
# The variable LATEST_LINK is named that way because the directory that "pkg_add -r" downloads from is called "Latest" and
# contains the "latest" versions of package as symbolic links to the files in the "All" directory.
- describe Chef::Provider::Package::Freebsd, "install_package latest link fixes" do
+ describe Chef::Provider::Package::Freebsd::Pkg, "install_package latest link fixes" do
it "should install the perl binary package with the correct name" do
@new_resource = Chef::Resource::Package.new("perl5.8")
@current_resource = Chef::Resource::Package.new("perl5.8")
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
@provider.stub(:package_name).and_return("perl")
@provider.stub(:latest_link_name).and_return("perl")
@@ -274,7 +261,7 @@ describe Chef::Provider::Package::Freebsd, "load_current_resource" do
@new_resource = Chef::Resource::Package.new("mysql50-server")
@current_resource = Chef::Resource::Package.new("mysql50-server")
- @provider = Chef::Provider::Package::Freebsd.new(@new_resource, @run_context)
+ @provider = Chef::Provider::Package::Freebsd::Pkg.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
@provider.stub(:package_name).and_return("mysql-server")
@provider.stub(:latest_link_name).and_return("mysql50-server")
diff --git a/spec/unit/provider/package/freebsd/pkgng_spec.rb b/spec/unit/provider/package/freebsd/pkgng_spec.rb
new file mode 100644
index 0000000000..001c9e23ba
--- /dev/null
+++ b/spec/unit/provider/package/freebsd/pkgng_spec.rb
@@ -0,0 +1,155 @@
+#
+# Authors:: Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+require 'spec_helper'
+require 'ostruct'
+
+describe Chef::Provider::Package::Freebsd::Port do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::Package.new("zsh")
+ @provider = Chef::Provider::Package::Freebsd::Pkgng.new(@new_resource, @run_context)
+ end
+
+
+ describe "initialization" do
+ it "should create a current resource with the name of the new resource" do
+ @provider.current_resource.is_a?(Chef::Resource::Package).should be_true
+ @provider.current_resource.name.should == 'zsh'
+ end
+ end
+
+
+ describe "loading current resource" do
+ before(:each) do
+ @provider.stub(:current_installed_version)
+ @provider.stub(:candidate_version)
+ end
+
+ it "should set the package name" do
+ @provider.load_current_resource
+ @provider.current_resource.package_name.should == "zsh"
+ end
+
+ it "should set the current version" do
+ @provider.should_receive(:current_installed_version).and_return("5.0.2")
+ @provider.load_current_resource
+ @provider.current_resource.version.should == "5.0.2"
+ end
+
+ it "should set the candidate version" do
+ @provider.should_receive(:candidate_version).and_return("5.0.5")
+ @provider.load_current_resource
+ @provider.instance_variable_get(:"@candidate_version").should == "5.0.5"
+ end
+ end
+
+
+ describe "determining current installed version" do
+ before(:each) do
+ @provider.stub(:supports_pkgng?)
+ @pkg_info = OpenStruct.new(:stdout => "zsh-3.1.7\n")
+ end
+
+ it "should query pkg database" do
+ @provider.should_receive(:shell_out!).with('pkg info "zsh"', :env => nil, :returns => [0,70]).and_return(@pkg_info)
+ @provider.current_installed_version.should == "3.1.7"
+ end
+ end
+
+
+ describe "determining candidate version" do
+ it "should query repository" do
+ pkg_query = OpenStruct.new(:stdout => "5.0.5\n", :exitstatus => 0)
+ @provider.should_receive(:shell_out!).with("pkg rquery '%v' zsh", :env => nil).and_return(pkg_query)
+ @provider.candidate_version.should == "5.0.5"
+ end
+
+ it "should query specified repository when given option" do
+ @provider.new_resource.options('-r LocalMirror') # This requires LocalMirror repo configuration.
+ pkg_query = OpenStruct.new(:stdout => "5.0.3\n", :exitstatus => 0)
+ @provider.should_receive(:shell_out!).with("pkg rquery -r LocalMirror '%v' zsh", :env => nil).and_return(pkg_query)
+ @provider.candidate_version.should == "5.0.3"
+ end
+
+ it "should return candidate version from file when given a file" do
+ @provider.new_resource.source("/nas/pkg/repo/zsh-5.0.1.txz")
+ @provider.candidate_version.should == "5.0.1"
+ end
+ end
+
+
+ describe "installing a binary package" do
+ before(:each) do
+ @install_result = OpenStruct.new(:status => true)
+ end
+
+ it "should handle package source from file" do
+ @provider.new_resource.source("/nas/pkg/repo/zsh-5.0.1.txz")
+ @provider.should_receive(:shell_out!).
+ with("pkg add /nas/pkg/repo/zsh-5.0.1.txz", :env => { 'LC_ALL' => nil }).
+ and_return(@install_result)
+ @provider.install_package("zsh", "5.0.1")
+ end
+
+ it "should handle package source over ftp or http" do
+ @provider.new_resource.source("http://repo.example.com/zsh-5.0.1.txz")
+ @provider.should_receive(:shell_out!).
+ with("pkg add http://repo.example.com/zsh-5.0.1.txz", :env => { 'LC_ALL' => nil }).
+ and_return(@install_result)
+ @provider.install_package("zsh", "5.0.1")
+ end
+
+ it "should handle a package name" do
+ @provider.should_receive(:shell_out!).
+ with("pkg install -y zsh", :env => { 'LC_ALL' => nil }).and_return(@install_result)
+ @provider.install_package("zsh", "5.0.1")
+ end
+
+ it "should handle a package name with a specified repo" do
+ @provider.new_resource.options('-r LocalMirror') # This requires LocalMirror repo configuration.
+ @provider.should_receive(:shell_out!).
+ with("pkg install -y -r LocalMirror zsh", :env => { 'LC_ALL' => nil }).and_return(@install_result)
+ @provider.install_package("zsh", "5.0.1")
+ end
+ end
+
+
+ describe "removing a binary package" do
+ before(:each) do
+ @install_result = OpenStruct.new(:status => true)
+ end
+
+ it "should call pkg delete" do
+ @provider.should_receive(:shell_out!).
+ with("pkg delete -y zsh-5.0.1", :env => nil).and_return(@install_result)
+ @provider.remove_package("zsh", "5.0.1")
+ end
+
+ it "should not include repo option in pkg delete" do
+ @provider.new_resource.options('-r LocalMirror') # This requires LocalMirror repo configuration.
+ @provider.should_receive(:shell_out!).
+ with("pkg delete -y zsh-5.0.1", :env => nil).and_return(@install_result)
+ @provider.remove_package("zsh", "5.0.1")
+ end
+ end
+end
diff --git a/spec/unit/provider/package/freebsd/port_spec.rb b/spec/unit/provider/package/freebsd/port_spec.rb
new file mode 100644
index 0000000000..e946719451
--- /dev/null
+++ b/spec/unit/provider/package/freebsd/port_spec.rb
@@ -0,0 +1,160 @@
+#
+# Authors:: Richard Manyanza (liseki@nyikacraftsmen.com)
+# Copyright:: Copyright (c) 2014 Richard Manyanza
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+require 'spec_helper'
+require 'ostruct'
+
+describe Chef::Provider::Package::Freebsd::Port do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::Package.new("zsh")
+ @provider = Chef::Provider::Package::Freebsd::Port.new(@new_resource, @run_context)
+ end
+
+
+ describe "initialization" do
+ it "should create a current resource with the name of the new resource" do
+ @provider.current_resource.is_a?(Chef::Resource::Package).should be_true
+ @provider.current_resource.name.should == 'zsh'
+ end
+ end
+
+
+ describe "loading current resource" do
+ before(:each) do
+ @provider.stub(:current_installed_version)
+ @provider.stub(:candidate_version)
+ end
+
+ it "should set the package name" do
+ @provider.load_current_resource
+ @provider.current_resource.package_name.should == "zsh"
+ end
+
+ it "should set the current version" do
+ @provider.should_receive(:current_installed_version).and_return("5.0.2")
+ @provider.load_current_resource
+ @provider.current_resource.version.should == "5.0.2"
+ end
+
+ it "should set the candidate version" do
+ @provider.should_receive(:candidate_version).and_return("5.0.5")
+ @provider.load_current_resource
+ @provider.instance_variable_get(:"@candidate_version").should == "5.0.5"
+ end
+ end
+
+
+ describe "determining current installed version" do
+ before(:each) do
+ @provider.stub(:supports_pkgng?)
+ @pkg_info = OpenStruct.new(:stdout => "zsh-3.1.7\n")
+ end
+
+ it "should check 'pkg_info' if system uses pkg_* tools" do
+ @provider.should_receive(:supports_pkgng?).and_return(false)
+ @provider.should_receive(:shell_out!).with('pkg_info -E "zsh*"', :env => nil, :returns => [0,1]).and_return(@pkg_info)
+ @provider.current_installed_version.should == "3.1.7"
+ end
+
+ it "should check 'pkg info' if system uses pkgng" do
+ @provider.should_receive(:supports_pkgng?).and_return(true)
+ @provider.should_receive(:shell_out!).with('pkg info "zsh"', :env => nil, :returns => [0,70]).and_return(@pkg_info)
+ @provider.current_installed_version.should == "3.1.7"
+ end
+ end
+
+
+ describe "determining candidate version" do
+ before(:each) do
+ @port_version = OpenStruct.new(:stdout => "5.0.5\n", :exitstatus => 0)
+ end
+
+ it "should return candidate version if port exists" do
+ ::File.stub(:exist?).with('/usr/ports/Makefile').and_return(true)
+ @provider.stub(:port_dir).and_return('/usr/ports/shells/zsh')
+ @provider.should_receive(:shell_out!).with("make -V PORTVERSION", :cwd => "/usr/ports/shells/zsh", :env => nil, :returns => [0,1]).
+ and_return(@port_version)
+ @provider.candidate_version.should == "5.0.5"
+ end
+
+ it "should raise exception if ports tree not found" do
+ ::File.stub(:exist?).with('/usr/ports/Makefile').and_return(false)
+ expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package, "Ports collection could not be found")
+ end
+ end
+
+
+ describe "determining port directory" do
+ it "should return name if package name is absolute path" do
+ @provider.new_resource.stub(:package_name).and_return("/var/ports/shells/zsh")
+ @provider.port_dir.should == "/var/ports/shells/zsh"
+ end
+
+ it "should return full ports path given package name and category" do
+ @provider.new_resource.stub(:package_name).and_return("shells/zsh")
+ @provider.port_dir.should == "/usr/ports/shells/zsh"
+ end
+
+ it "should query system for path given just a name" do
+ whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh\n")
+ @provider.should_receive(:shell_out!).with("whereis -s zsh", :env => nil).and_return(whereis)
+ @provider.port_dir.should == "/usr/ports/shells/zsh"
+ end
+
+ it "should raise exception if not found" do
+ whereis = OpenStruct.new(:stdout => "zsh:\n")
+ @provider.should_receive(:shell_out!).with("whereis -s zsh", :env => nil).and_return(whereis)
+ expect { @provider.port_dir }.to raise_error(Chef::Exceptions::Package, "Could not find port with the name zsh")
+ end
+ end
+
+
+ describe "building a binary package" do
+ before(:each) do
+ @install_result = OpenStruct.new(:status => true)
+ end
+
+ it "should run make install in port directory" do
+ @provider.stub(:port_dir).and_return("/usr/ports/shells/zsh")
+ @provider.should_receive(:shell_out!).
+ with("make -DBATCH install clean", :timeout => 1800, :cwd => "/usr/ports/shells/zsh", :env => nil).
+ and_return(@install_result)
+ @provider.install_package("zsh", "5.0.5")
+ end
+ end
+
+
+ describe "removing a binary package" do
+ before(:each) do
+ @install_result = OpenStruct.new(:status => true)
+ end
+
+ it "should run make deinstall in port directory" do
+ @provider.stub(:port_dir).and_return("/usr/ports/shells/zsh")
+ @provider.should_receive(:shell_out!).
+ with("make deinstall", :timeout => 300, :cwd => "/usr/ports/shells/zsh", :env => nil).
+ and_return(@install_result)
+ @provider.remove_package("zsh", "5.0.5")
+ end
+ end
+end
diff --git a/spec/unit/resource/freebsd_package_spec.rb b/spec/unit/resource/freebsd_package_spec.rb
index b80a94f98d..ae12abac6e 100644
--- a/spec/unit/resource/freebsd_package_spec.rb
+++ b/spec/unit/resource/freebsd_package_spec.rb
@@ -1,6 +1,8 @@
#
-# Author:: AJ Christensen (<aj@opscode.com>)
+# Authors:: AJ Christensen (<aj@opscode.com>)
+# Richard Manyanza (<liseki@nyikacraftsmen.com>)
# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Copyright:: Copyright (c) 2014 Richard Manyanza.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,23 +19,73 @@
#
require 'spec_helper'
+require 'ostruct'
-describe Chef::Resource::FreebsdPackage, "initialize" do
-
+describe Chef::Resource::FreebsdPackage do
before(:each) do
- @resource = Chef::Resource::FreebsdPackage.new("foo")
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @resource = Chef::Resource::FreebsdPackage.new("foo", @run_context)
end
- it "should return a Chef::Resource::FreebsdPackage" do
- @resource.should be_a_kind_of(Chef::Resource::FreebsdPackage)
- end
- it "should set the resource_name to :freebsd_package" do
- @resource.resource_name.should eql(:freebsd_package)
+ describe "Initialization" do
+ it "should return a Chef::Resource::FreebsdPackage" do
+ @resource.should be_a_kind_of(Chef::Resource::FreebsdPackage)
+ end
+
+ it "should set the resource_name to :freebsd_package" do
+ @resource.resource_name.should eql(:freebsd_package)
+ end
+
+ it "should not set the provider" do
+ @resource.provider.should be_nil
+ end
end
- it "should set the provider to Chef::Provider::Package::freebsd" do
- @resource.provider.should eql(Chef::Provider::Package::Freebsd)
+
+ describe "Assigning provider after creation" do
+ describe "if ports specified as source" do
+ it "should be Freebsd::Port" do
+ @resource.source('ports')
+ @resource.after_created
+ @resource.provider.should == Chef::Provider::Package::Freebsd::Port
+ end
+ end
+
+ describe "if __Freebsd_version is greater than or equal to 1000017" do
+ it "should be Freebsd::Pkgng" do
+ [1000017, 1000018, 1000500, 1001001, 1100000].each do |__freebsd_version|
+ @node.normal[:os_version] = __freebsd_version
+ @resource.after_created
+ @resource.provider.should == Chef::Provider::Package::Freebsd::Pkgng
+ end
+ end
+ end
+
+ describe "if pkgng enabled" do
+ it "should be Freebsd::Pkgng" do
+ pkg_enabled = OpenStruct.new(:stdout => "yes\n")
+ @resource.stub(:shell_out!).with("make -V WITH_PKGNG", :env => nil).and_return(pkg_enabled)
+ @resource.after_created
+ @resource.provider.should == Chef::Provider::Package::Freebsd::Pkgng
+ end
+ end
+
+ describe "if __Freebsd_version is less than 1000017 and pkgng not enabled" do
+ it "should be Freebsd::Pkg" do
+ pkg_enabled = OpenStruct.new(:stdout => "\n")
+ @resource.stub(:shell_out!).with("make -V WITH_PKGNG", :env => nil).and_return(pkg_enabled)
+
+ [1000016, 1000000, 901503, 902506, 802511].each do |__freebsd_version|
+ @node[:os_version] == __freebsd_version
+ @node.normal[:os_version] = __freebsd_version
+ @resource.after_created
+ @resource.provider.should == Chef::Provider::Package::Freebsd::Pkg
+ end
+ end
+ end
end
end
diff --git a/spec/unit/version/platform_spec.rb b/spec/unit/version/platform_spec.rb
index 8b5b3503dc..69f42e58b2 100644
--- a/spec/unit/version/platform_spec.rb
+++ b/spec/unit/version/platform_spec.rb
@@ -30,7 +30,7 @@ describe Chef::Version::Platform do
end
describe "when creating valid Versions" do
- good_versions = %w(1 1.2 1.2.3 1000.80.50000 0.300.25 001.02.00003)
+ good_versions = %w(1 1.2 1.2.3 1000.80.50000 0.300.25 001.02.00003 1.2-STABLE 10.0-BETA3 9.1-RELEASE-p3)
good_versions.each do |v|
it "should accept '#{v}'" do
Chef::Version::Platform.new v