summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Martin <max@puppetlabs.com>2011-04-13 16:52:20 -0700
committerMax Martin <max@puppetlabs.com>2011-04-13 16:52:20 -0700
commitd9d9709c1eac46a94160dd75de34eafeb6c6de0c (patch)
treed86a85e406a70f6dc062af0d823d7ed1bfa5695b
parentda4457be4dedaed5368bacf81a08f0429e21cd45 (diff)
parent6a8068b3912d6275efe4005258a06d03363c8944 (diff)
downloadpuppet-d9d9709c1eac46a94160dd75de34eafeb6c6de0c.tar.gz
puppet-d9d9709c1eac46a94160dd75de34eafeb6c6de0c.tar.xz
puppet-d9d9709c1eac46a94160dd75de34eafeb6c6de0c.zip
Merge branch '2.6.next' into 2.6.x
* 2.6.next: (#2331) Remove darwinports pkg provider, replace with rewritten macports provider Fixed #7082 - Added system support for groups (#7018) Give more context on the service type's assumptions. Wording tweaks. (#7018) explain internals better in service provider documentation maint: Fix sqlite3 require to really be optional maint: Fix sporadic sqlite error (#6818) Stop from getting Rails 3 named_scope deprecation warning (#6856) Copy dangling symlinks with 'links => manage' File resource.
-rw-r--r--lib/puppet/provider/group/groupadd.rb3
-rwxr-xr-xlib/puppet/provider/package/darwinport.rb86
-rwxr-xr-xlib/puppet/provider/package/macports.rb106
-rw-r--r--lib/puppet/rails/inventory_node.rb5
-rwxr-xr-xlib/puppet/type/file/source.rb1
-rwxr-xr-xlib/puppet/type/group.rb12
-rw-r--r--lib/puppet/type/service.rb30
-rw-r--r--spec/unit/indirector/facts/inventory_active_record_spec.rb6
-rwxr-xr-xspec/unit/provider/group/groupadd_spec.rb12
-rwxr-xr-xspec/unit/provider/package/macports_spec.rb122
-rwxr-xr-xspec/unit/type/file/source_spec.rb1
-rwxr-xr-xspec/unit/type/group_spec.rb9
12 files changed, 292 insertions, 101 deletions
diff --git a/lib/puppet/provider/group/groupadd.rb b/lib/puppet/provider/group/groupadd.rb
index 82ed4c0c7..bcc08d9f7 100644
--- a/lib/puppet/provider/group/groupadd.rb
+++ b/lib/puppet/provider/group/groupadd.rb
@@ -9,6 +9,8 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
commands :add => "groupadd", :delete => "groupdel", :modify => "groupmod"
+ has_feature :system_groups
+
verify :gid, "GID must be an integer" do |value|
value.is_a? Integer
end
@@ -21,6 +23,7 @@ Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameSe
end
end
cmd << "-o" if @resource.allowdupe?
+ cmd << "-r" if @resource.system?
cmd << @resource[:name]
cmd
diff --git a/lib/puppet/provider/package/darwinport.rb b/lib/puppet/provider/package/darwinport.rb
deleted file mode 100755
index c5f9ba28f..000000000
--- a/lib/puppet/provider/package/darwinport.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-require 'puppet/provider/package'
-
-Puppet::Type.type(:package).provide :darwinport, :parent => Puppet::Provider::Package do
- desc "Package management using DarwinPorts on OS X."
-
- confine :operatingsystem => :darwin
- commands :port => "/opt/local/bin/port"
-
- def self.eachpkgashash
- # list out all of the packages
- open("| #{command(:port)} list installed") { |process|
- regex = %r{(\S+)\s+@(\S+)\s+(\S+)}
- fields = [:name, :ensure, :location]
- hash = {}
-
- # now turn each returned line into a package object
- process.each { |line|
- hash.clear
-
- if match = regex.match(line)
- fields.zip(match.captures) { |field,value|
- hash[field] = value
- }
-
- hash.delete :location
- hash[:provider] = self.name
- yield hash.dup
- else
- raise Puppet::DevError,
- "Failed to match dpkg line #{line}"
- end
- }
- }
- end
-
- def self.instances
- packages = []
-
- eachpkgashash do |hash|
- packages << new(hash)
- end
-
- packages
- end
-
- def install
- should = @resource.should(:ensure)
-
- # Seems like you can always say 'upgrade'
- output = port "upgrade", @resource[:name]
- if output =~ /^Error: No port/
- raise Puppet::ExecutionFailure, "Could not find package #{@resource[:name]}"
- end
- end
-
- def query
- version = nil
- self.class.eachpkgashash do |hash|
- return hash if hash[:name] == @resource[:name]
- end
-
- nil
- end
-
- def latest
- info = port :search, "^#{@resource[:name]}$"
-
- if $CHILD_STATUS != 0 or info =~ /^Error/
- return nil
- end
-
- ary = info.split(/\s+/)
- version = ary[2].sub(/^@/, '')
-
- version
- end
-
- def uninstall
- port :uninstall, @resource[:name]
- end
-
- def update
- install
- end
-end
-
diff --git a/lib/puppet/provider/package/macports.rb b/lib/puppet/provider/package/macports.rb
new file mode 100755
index 000000000..c43eb72f3
--- /dev/null
+++ b/lib/puppet/provider/package/macports.rb
@@ -0,0 +1,106 @@
+require 'puppet/provider/package'
+
+Puppet::Type.type(:package).provide :macports, :parent => Puppet::Provider::Package do
+ desc "Package management using MacPorts on OS X.
+
+ Supports MacPorts versions and revisions, but not variants.
+ Variant preferences may be specified using the MacPorts variants.conf file
+ http://guide.macports.org/chunked/internals.configuration-files.html#internals.configuration-files.variants-conf
+
+ When specifying a version in the Puppet DSL, only specify the version, not the revision
+ Revisions are only used internally for ensuring the latest version/revision of a port.
+ "
+
+ confine :operatingsystem => :darwin
+ commands :port => "/opt/local/bin/port"
+
+ has_feature :installable
+ has_feature :uninstallable
+ has_feature :upgradeable
+ has_feature :versionable
+
+
+ def self.parse_installed_query_line(line)
+ regex = /(\S+)\s+@(\S+)_(\S+)\s+\(active\)/
+ fields = [:name, :ensure, :revision]
+ hash_from_line(line, regex, fields)
+ end
+
+ def self.parse_info_query_line(line)
+ regex = /(\S+)\s+(\S+)/
+ fields = [:version, :revision]
+ hash_from_line(line, regex, fields)
+ end
+
+ def self.hash_from_line(line, regex, fields)
+ hash = {}
+ if match = regex.match(line)
+ fields.zip(match.captures) { |field, value|
+ hash[field] = value
+ }
+ hash[:provider] = self.name
+ return hash
+ end
+ nil
+ end
+
+ def self.instances
+ packages = []
+ port("-q", :installed).each do |line|
+ if hash = parse_installed_query_line(line)
+ packages << new(hash)
+ end
+ end
+ packages
+ end
+
+ def install
+ should = @resource.should(:ensure)
+ if [:latest, :installed, :present].include?(should)
+ output = port("-q", :install, @resource[:name])
+ else
+ output = port("-q", :install, @resource[:name], "@#{should}")
+ end
+ # MacPorts now correctly exits non-zero with appropriate errors in
+ # situations where a port cannot be found or installed.
+ end
+
+ def query
+ return self.class.parse_installed_query_line(port("-q", :installed, @resource[:name]))
+ end
+
+ def latest
+ # We need both the version and the revision to be confident
+ # we've got the latest revision of a specific version
+ # Note we're still not doing anything with variants here.
+ info_line = port("-q", :info, "--line", "--version", "--revision", @resource[:name])
+ return nil if info_line == ""
+
+ if newest = self.class.parse_info_query_line(info_line)
+ current = query
+ # We're doing some fiddling behind the scenes here to cope with updated revisions.
+ # If we're already at the latest version/revision, then just return the version
+ # so the current and desired values match. Otherwise return version and revision
+ # to trigger an upgrade to the latest revision.
+ if newest[:version] == current[:ensure] and newest[:revision] == current[:revision]
+ return current[:ensure]
+ else
+ return "#{newest[:version]}_#{newest[:revision]}"
+ end
+ end
+ nil
+ end
+
+ def uninstall
+ port("-q", :uninstall, @resource[:name])
+ end
+
+ def update
+ if query[:name] == @resource[:name] # 'port upgrade' cannot install new ports
+ port("-q", :upgrade, @resource[:name])
+ else
+ install
+ end
+ end
+end
+
diff --git a/lib/puppet/rails/inventory_node.rb b/lib/puppet/rails/inventory_node.rb
index 52f8621a4..da7e61040 100644
--- a/lib/puppet/rails/inventory_node.rb
+++ b/lib/puppet/rails/inventory_node.rb
@@ -3,6 +3,11 @@ require 'puppet/rails/inventory_fact'
class Puppet::Rails::InventoryNode < ::ActiveRecord::Base
has_many :facts, :class_name => "Puppet::Rails::InventoryFact", :foreign_key => :node_id, :dependent => :delete_all
+ if Puppet::Util.activerecord_version >= 3.0
+ # Prevents "DEPRECATION WARNING: Base.named_scope has been deprecated, please use Base.scope instead"
+ ActiveRecord::NamedScope::ClassMethods.module_eval { alias :named_scope :scope }
+ end
+
named_scope :has_fact_with_value, lambda { |name,value|
{
:conditions => ["inventory_facts.name = ? AND inventory_facts.value = ?", name, value],
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 6dda7957c..6ebec51fe 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -114,6 +114,7 @@ module Puppet
param_name = (metadata_method == :checksum) ? :content : metadata_method
next if metadata_method == :owner and !Puppet.features.root?
next if metadata_method == :checksum and metadata.ftype == "directory"
+ next if metadata_method == :checksum and metadata.ftype == "link" and metadata.links == :manage
if resource[param_name].nil? or resource[param_name] == :absent
resource[param_name] = metadata.send(metadata_method)
diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb
index cde1cfd65..066bd49df 100755
--- a/lib/puppet/type/group.rb
+++ b/lib/puppet/type/group.rb
@@ -1,4 +1,3 @@
-
require 'etc'
require 'facter'
@@ -15,6 +14,9 @@ module Puppet
feature :manages_members,
"For directories where membership is an attribute of groups not users."
+ feature :system_groups,
+ "The provider allows you to create system groups with lower GIDs."
+
ensurable do
desc "Create or remove the group."
@@ -95,5 +97,13 @@ module Puppet
defaultto false
end
+
+ newparam(:system, :boolean => true) do
+ desc "Whether the group is a system group with lower GID."
+
+ newvalues(:true, :false)
+
+ defaultto false
+ end
end
end
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index 0d09c3d5d..3658e2837 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -8,19 +8,24 @@ module Puppet
newtype(:service) do
@doc = "Manage running services. Service support unfortunately varies
- widely by platform -- some platforms have very little if any
+ widely by platform --- some platforms have very little if any
concept of a running service, and some have a very codified and
powerful concept. Puppet's service support will generally be able
- to make up for any inherent shortcomings (e.g., if there is no
+ to do the right thing regardless (e.g., if there is no
'status' command, then Puppet will look in the process table for a
command matching the service name), but the more information you
- can provide the better behaviour you will get. Or, you can just
- use a platform that has very good service support.
+ can provide, the better behaviour you will get. In particular, any
+ virtual services that don't have a predictable entry in the process table
+ (for example, `network` on Red Hat/CentOS systems) will manifest odd
+ behavior on restarts if you don't specify `hasstatus` or a `status`
+ command.
Note that if a `service` receives an event from another resource,
the service will get restarted. The actual command to restart the
- service depends on the platform. You can provide a special command
- for restarting with the `restart` attribute."
+ service depends on the platform. You can provide an explicit command
+ for restarting with the `restart` attribute, or use the init script's
+ restart command with the `hasrestart` attribute; if you do neither,
+ the service's stop and start commands will be used."
feature :refreshable, "The provider can restart the service.",
:methods => [:restart]
@@ -93,11 +98,14 @@ module Puppet
that a large number of init scripts on different platforms do
not support any kind of status command; thus, you must specify
manually whether the service you are running has such a
- command (or you can specify a specific command using the
- `status` parameter).
-
- If you do not specify anything, then the service name will be
- looked for in the process table."
+ command. Alternately, you can provide a specific command using the
+ `status` attribute.
+
+ If you specify neither of these, then Puppet will look for the
+ service name in the process table. Be aware that 'virtual' init
+ scripts such as networking will respond poorly to refresh events
+ (via notify and subscribe relationships) if you don't override
+ this default behavior."
newvalues(:true, :false)
end
diff --git a/spec/unit/indirector/facts/inventory_active_record_spec.rb b/spec/unit/indirector/facts/inventory_active_record_spec.rb
index 9558abde2..022150c76 100644
--- a/spec/unit/indirector/facts/inventory_active_record_spec.rb
+++ b/spec/unit/indirector/facts/inventory_active_record_spec.rb
@@ -1,7 +1,10 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../spec_helper'
-require 'sqlite3' rescue nil
+begin
+ require 'sqlite3'
+rescue LoadError
+end
require 'tempfile'
require 'puppet/rails'
@@ -29,6 +32,7 @@ describe "Puppet::Node::Facts::InventoryActiveRecord", :if => (Puppet.features.r
after :each do
Puppet::Rails.teardown
+ ActiveRecord::Base.remove_connection
end
describe "#save" do
diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb
index 33d9acd98..65cc887e4 100755
--- a/spec/unit/provider/group/groupadd_spec.rb
+++ b/spec/unit/provider/group/groupadd_spec.rb
@@ -10,10 +10,10 @@ describe provider_class do
@provider = provider_class.new(@resource)
end
- # #1360
it "should add -o when allowdupe is enabled and the group is being created" do
@resource.stubs(:should).returns "fakeval"
@resource.stubs(:[]).returns "fakeval"
+ @resource.stubs(:system?).returns true
@resource.expects(:allowdupe?).returns true
@provider.expects(:execute).with { |args| args.include?("-o") }
@@ -28,4 +28,14 @@ describe provider_class do
@provider.gid = 150
end
+
+ it "should add -r when system is enabled and the group is being created" do
+ @resource.stubs(:should).returns "fakeval"
+ @resource.stubs(:[]).returns "fakeval"
+ @resource.expects(:system?).returns true
+ @resource.stubs(:allowdupe?).returns true
+ @provider.expects(:execute).with { |args| args.include?("-r") }
+
+ @provider.create
+ end
end
diff --git a/spec/unit/provider/package/macports_spec.rb b/spec/unit/provider/package/macports_spec.rb
new file mode 100755
index 000000000..7d1acd537
--- /dev/null
+++ b/spec/unit/provider/package/macports_spec.rb
@@ -0,0 +1,122 @@
+require 'spec_helper'
+
+provider_class = Puppet::Type.type(:package).provider(:macports)
+
+describe provider_class do
+ let :resource_name do
+ "foo"
+ end
+
+ let :resource do
+ Puppet::Type.type(:package).new(:name => resource_name, :provider => :macports)
+ end
+
+ let :provider do
+ prov = resource.provider
+ prov.expects(:execute).never
+ prov
+ end
+
+ let :current_hash do
+ {:name => resource_name, :ensure => "1.2.3", :revision => "1", :provider => :macports}
+ end
+
+ describe "provider features" do
+ subject { provider }
+
+ it { should be_installable }
+ it { should be_uninstallable }
+ it { should be_upgradeable }
+ it { should be_versionable }
+ end
+
+ describe "when listing all instances" do
+ it "should call port -q installed" do
+ provider_class.expects(:port).with("-q", :installed).returns("")
+ provider_class.instances
+ end
+
+ it "should create instances from active ports" do
+ provider_class.expects(:port).returns("foo @1.234.5_2 (active)")
+ provider_class.instances.size.should == 1
+ end
+
+ it "should ignore ports that aren't activated" do
+ provider_class.expects(:port).returns("foo @1.234.5_2")
+ provider_class.instances.size.should == 0
+ end
+ end
+
+ describe "when installing" do
+ it "should not specify a version when ensure is set to latest" do
+ resource[:ensure] = :latest
+ provider.expects(:port).with { |flag, method, name, version|
+ version.should be_nil
+ }
+ provider.install
+ end
+
+ it "should not specify a version when ensure is set to present" do
+ resource[:ensure] = :present
+ provider.expects(:port).with { |flag, method, name, version|
+ version.should be_nil
+ }
+ provider.install
+ end
+
+ it "should specify a version when ensure is set to a version" do
+ resource[:ensure] = "1.2.3"
+ provider.expects(:port).with { |flag, method, name, version|
+ version.should be
+ }
+ provider.install
+ end
+ end
+
+ describe "when querying for the latest version" do
+ let :new_info_line do
+ "1.2.3 2"
+ end
+ let :infoargs do
+ ["-q", :info, "--line", "--version", "--revision", resource_name]
+ end
+
+ it "should return nil when the package cannot be found" do
+ resource[:name] = resource_name
+ provider.expects(:port).returns("")
+ provider.latest.should == nil
+ end
+
+ it "should return the current version if the installed port has the same revision" do
+ current_hash[:revision] = "2"
+ provider.expects(:port).with(*infoargs).returns(new_info_line)
+ provider.expects(:query).returns(current_hash)
+ provider.latest.should == current_hash[:ensure]
+ end
+
+ it "should return the new version_revision if the installed port has a lower revision" do
+ current_hash[:revision] = "1"
+ provider.expects(:port).with(*infoargs).returns(new_info_line)
+ provider.expects(:query).returns(current_hash)
+ provider.latest.should == "1.2.3_2"
+ end
+ end
+
+ describe "when updating a port" do
+ it "should execute port upgrade if the port is installed" do
+ resource[:name] = resource_name
+ resource[:ensure] = :present
+ provider.expects(:query).returns(current_hash)
+ provider.expects(:port).with("-q", :upgrade, resource_name)
+ provider.update
+ end
+
+ it "should execute port install if the port is not installed" do
+ resource[:name] = resource_name
+ resource[:ensure] = :present
+ provider.expects(:query).returns("")
+ provider.expects(:port).with("-q", :install, resource_name)
+ provider.update
+ end
+ end
+end
diff --git a/spec/unit/type/file/source_spec.rb b/spec/unit/type/file/source_spec.rb
index 00cc2f235..6e04fa2a5 100755
--- a/spec/unit/type/file/source_spec.rb
+++ b/spec/unit/type/file/source_spec.rb
@@ -187,6 +187,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do
describe "and the source is a link" do
it "should set the target to the link destination" do
@metadata.stubs(:ftype).returns "link"
+ @metadata.stubs(:links).returns "manage"
@resource.stubs(:[])
@resource.stubs(:[]=)
diff --git a/spec/unit/type/group_spec.rb b/spec/unit/type/group_spec.rb
index b41ce71a0..e373dac6e 100755
--- a/spec/unit/type/group_spec.rb
+++ b/spec/unit/type/group_spec.rb
@@ -16,6 +16,10 @@ describe Puppet::Type.type(:group) do
@class.defaultprovider.ancestors.should be_include(Puppet::Provider)
end
+ it "should have a system_groups feature" do
+ @class.provider_feature(:system_groups).should_not be_nil
+ end
+
describe "when validating attributes" do
[:name, :allowdupe].each do |param|
it "should have a #{param} parameter" do
@@ -38,11 +42,14 @@ describe Puppet::Type.type(:group) do
end
end
- # #1407 - we need to declare the allowdupe param as boolean.
it "should have a boolean method for determining if duplicates are allowed" do
@class.new(:name => "foo").methods.should be_include("allowdupe?")
end
+ it "should have a boolean method for determining if system groups are allowed" do
+ @class.new(:name => "foo").methods.should be_include("system?")
+ end
+
it "should call 'create' to create the group" do
group = @class.new(:name => "foo", :ensure => :present)
group.provider.expects(:create)