[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35
James Turnbull
james at lovedthanlost.net
Wed Jul 14 10:29:37 UTC 2010
The following commit has been merged in the upstream branch:
commit adc211ad191568e84eb3e1f618f1cbf78df95ba9
Author: Luke Kanies <luke at madstop.com>
Date: Fri Oct 2 12:08:56 2009 -0700
Adding module metadata
This is a first version that does very little -
it has a few fields, and allows speciification of
dependencies with other modules as well as compatibility
with individual Puppet versions.
It's not really sufficient, because it only allows specific
versions, rather than a range of versions, but it's a good
demo of what it takes and what we provide.
Signed-off-by: Luke Kanies <luke at madstop.com>
diff --git a/lib/puppet/module.rb b/lib/puppet/module.rb
index 9aa634b..b0d80ca 100644
--- a/lib/puppet/module.rb
+++ b/lib/puppet/module.rb
@@ -2,6 +2,12 @@ require 'puppet/util/logging'
# Support for modules
class Puppet::Module
+ class MissingModule < Puppet::Error; end
+ class IncompatibleModule < Puppet::Error; end
+ class UnsupportedPlatform < Puppet::Error; end
+ class IncompatiblePlatform < Puppet::Error; end
+ class MissingMetadata < Puppet::Error; end
+
include Puppet::Util::Logging
class InvalidName < ArgumentError
@@ -35,6 +41,14 @@ class Puppet::Module
attr_reader :name, :environment
attr_writer :environment
+ attr_accessor :source, :author, :version, :license, :puppetversion, :summary, :description, :project_page
+
+ def has_metadata?
+ return false unless metadata_file
+
+ FileTest.exist?(metadata_file)
+ end
+
def initialize(name, environment = nil)
@name = name
@@ -45,6 +59,11 @@ class Puppet::Module
else
@environment = Puppet::Node::Environment.new(environment)
end
+
+ load_metadata if has_metadata?
+
+ validate_puppet_version
+ validate_dependencies
end
FILETYPES.each do |type|
@@ -86,6 +105,25 @@ class Puppet::Module
subpath("files")
end
+ def license_file
+ return @license_file if defined?(@license_file)
+
+ return @license_file = nil unless path
+ @license_file = File.join(path, "License")
+ end
+
+ def load_metadata
+ data = JSON.parse File.read(metadata_file)
+ [:source, :author, :version, :license, :puppetversion].each do |attr|
+ unless value = data[attr.to_s]
+ unless attr == :puppetversion
+ raise MissingMetadata, "No #{attr} module metadata provided for #{self.name}"
+ end
+ end
+ send(attr.to_s + "=", value)
+ end
+ end
+
# Return the list of manifests matching the given glob pattern,
# defaulting to 'init.pp' for empty modules.
def match_manifests(rest)
@@ -100,6 +138,13 @@ class Puppet::Module
result.flatten.compact
end
+ def metadata_file
+ return @metadata_file if defined?(@metadata_file)
+
+ return @metadata_file = nil unless path
+ @metadata_file = File.join(path, "metadata.json")
+ end
+
# Find this module in the modulepath.
def path
environment.modulepath.collect { |path| File.join(path, name) }.find { |d| FileTest.exist?(d) }
@@ -110,6 +155,16 @@ class Puppet::Module
subpath("plugins")
end
+ def requires(name, version = nil)
+ @requires ||= []
+ @requires << [name, version]
+ end
+
+ def supports(name, version = nil)
+ @supports ||= []
+ @supports << [name, version]
+ end
+
def to_s
result = "Module %s" % name
if path
@@ -118,6 +173,25 @@ class Puppet::Module
result
end
+ def validate_dependencies
+ return unless defined?(@requires)
+
+ @requires.each do |name, version|
+ unless mod = environment.module(name)
+ raise MissingModule, "Missing module #{name} required by #{self.name}"
+ end
+
+ if version and mod.version != version
+ raise IncompatibleModule, "Required module #{name} is version #{mod.version} but #{self.name} requires #{version}"
+ end
+ end
+ end
+
+ def validate_puppet_version
+ return unless puppetversion and puppetversion != Puppet.version
+ raise IncompatibleModule, "Module #{self.name} is only compatible with Puppet version #{puppetversion}, not #{Puppet.version}"
+ end
+
private
def find_init_manifest
diff --git a/spec/unit/module.rb b/spec/unit/module.rb
index 4fa6ec5..e6623be 100755
--- a/spec/unit/module.rb
+++ b/spec/unit/module.rb
@@ -25,6 +25,203 @@ describe Puppet::Module do
Puppet::Module.find("mymod", "myenv").should be_nil
end
+ it "should support a 'version' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.version = 1.09
+ mod.version.should == 1.09
+ end
+
+ it "should support a 'source' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.source = "http://foo/bar"
+ mod.source.should == "http://foo/bar"
+ end
+
+ it "should support a 'project_page' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.project_page = "http://foo/bar"
+ mod.project_page.should == "http://foo/bar"
+ end
+
+ it "should support an 'author' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.author = "Luke Kanies <luke at madstop.com>"
+ mod.author.should == "Luke Kanies <luke at madstop.com>"
+ end
+
+ it "should support a 'license' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.license = "GPL2"
+ mod.license.should == "GPL2"
+ end
+
+ it "should support a 'summary' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.summary = "GPL2"
+ mod.summary.should == "GPL2"
+ end
+
+ it "should support a 'description' attribute" do
+ mod = Puppet::Module.new("mymod")
+ mod.description = "GPL2"
+ mod.description.should == "GPL2"
+ end
+
+ it "should support specifying a compatible puppet version" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ mod.puppetversion.should == "0.25"
+ end
+
+ it "should validate that the puppet version is compatible" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ Puppet.expects(:version).returns "0.25"
+ mod.validate_puppet_version
+ end
+
+ it "should fail if the specified puppet version is not compatible" do
+ mod = Puppet::Module.new("mymod")
+ mod.puppetversion = "0.25"
+ Puppet.stubs(:version).returns "0.24"
+ lambda { mod.validate_puppet_version }.should raise_error(Puppet::Module::IncompatibleModule)
+ end
+
+ describe "when specifying required modules" do
+ it "should support specifying a required module" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+ end
+
+ it "should support specifying multiple required modules" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+ mod.requires "baz"
+ end
+
+ it "should support specifying a required module and version" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
+ end
+
+ it "should fail when required modules are missing" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+
+ mod.environment.expects(:module).with("foobar").returns nil
+
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
+ end
+
+ it "should fail when required modules are present but of the wrong version" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
+
+ foobar = Puppet::Module.new("foobar")
+ foobar.version = 2.0
+
+ mod.environment.expects(:module).with("foobar").returns foobar
+
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::IncompatibleModule)
+ end
+
+ it "should have valid dependencies when no dependencies have been specified" do
+ mod = Puppet::Module.new("mymod")
+
+ lambda { mod.validate_dependencies }.should_not raise_error
+ end
+
+ it "should fail when some dependencies are present but others aren't" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar"
+ mod.requires "baz"
+
+ mod.environment.expects(:module).with("foobar").returns Puppet::Module.new("foobar")
+ mod.environment.expects(:module).with("baz").returns nil
+
+ lambda { mod.validate_dependencies }.should raise_error(Puppet::Module::MissingModule)
+ end
+
+ it "should have valid dependencies when all dependencies are met" do
+ mod = Puppet::Module.new("mymod")
+ mod.requires "foobar", 1.0
+ mod.requires "baz"
+
+ foobar = Puppet::Module.new("foobar")
+ foobar.version = 1.0
+
+ baz = Puppet::Module.new("baz")
+
+ mod.environment.expects(:module).with("foobar").returns foobar
+ mod.environment.expects(:module).with("baz").returns baz
+
+ lambda { mod.validate_dependencies }.should_not raise_error
+ end
+
+ it "should validate its dependendencies on initialization" do
+ Puppet::Module.any_instance.expects(:validate_dependencies)
+ Puppet::Module.new("mymod")
+ end
+ end
+
+ describe "when managing supported platforms" do
+ it "should support specifying a supported platform" do
+ mod = Puppet::Module.new("mymod")
+ mod.supports "solaris"
+ end
+
+ it "should support specifying a supported platform and version" do
+ mod = Puppet::Module.new("mymod")
+ mod.supports "solaris", 1.0
+ end
+
+ it "should fail when not running on a supported platform" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
+
+ mod.supports "hpux"
+
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::UnsupportedPlatform)
+ end
+
+ it "should fail when supported platforms are present but of the wrong version" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
+ Facter.expects(:value).with("operatingsystemrelease").returns 2.0
+
+ mod.supports "Solaris", 1.0
+
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
+ end
+
+ it "should be considered supported when no supported platforms have been specified" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ lambda { mod.validate_supported_platform }.should_not raise_error
+ end
+
+ it "should be considered supported when running on a supported platform" do
+ pending "Not sure how to send client platform to the module"
+ mod = Puppet::Module.new("mymod")
+ Facter.expects(:value).with("operatingsystem").returns "Solaris"
+ Facter.expects(:value).with("operatingsystemrelease").returns 2.0
+
+ mod.supports "Solaris", 1.0
+
+ lambda { mod.validate_supported_platform }.should raise_error(Puppet::Module::IncompatiblePlatform)
+ end
+
+ it "should be considered supported when running on any of multiple supported platforms" do
+ pending "Not sure how to send client platform to the module"
+ end
+
+ it "should validate its platform support on initialization" do
+ pending "Not sure how to send client platform to the module"
+ end
+ end
+
it "should return nil if asked for a module whose name is 'nil'" do
Puppet::Module.find(nil, "myenv").should be_nil
end
@@ -245,3 +442,104 @@ describe Puppet::Module, "when finding matching manifests" do
@mod.match_manifests("yay/*.pp").should == []
end
end
+
+describe Puppet::Module do
+ before do
+ Puppet::Module.any_instance.stubs(:path).returns "/my/mod/path"
+ @module = Puppet::Module.new("foo")
+ end
+
+ it "should use 'License' in its current path as its metadata file" do
+ @module.license_file.should == "/my/mod/path/License"
+ end
+
+ it "should return nil as its license file when the module has no path" do
+ Puppet::Module.any_instance.stubs(:path).returns nil
+ Puppet::Module.new("foo").license_file.should be_nil
+ end
+
+ it "should cache the license file" do
+ Puppet::Module.any_instance.expects(:path).once.returns nil
+ mod = Puppet::Module.new("foo")
+ mod.license_file.should == mod.license_file
+ end
+
+ it "should use 'metadata.json' in its current path as its metadata file" do
+ @module.metadata_file.should == "/my/mod/path/metadata.json"
+ end
+
+ it "should return nil as its metadata file when the module has no path" do
+ Puppet::Module.any_instance.stubs(:path).returns nil
+ Puppet::Module.new("foo").metadata_file.should be_nil
+ end
+
+ it "should cache the metadata file" do
+ Puppet::Module.any_instance.expects(:path).once.returns nil
+ mod = Puppet::Module.new("foo")
+ mod.metadata_file.should == mod.metadata_file
+ end
+
+ it "should know if it has a metadata file" do
+ FileTest.expects(:exist?).with(@module.metadata_file).returns true
+
+ @module.should be_has_metadata
+ end
+
+ it "should know if it is missing a metadata file" do
+ FileTest.expects(:exist?).with(@module.metadata_file).returns false
+
+ @module.should_not be_has_metadata
+ end
+
+ it "should be able to parse its metadata file" do
+ @module.should respond_to(:load_metadata)
+ end
+
+ it "should parse its metadata file on initialization if it is present" do
+ Puppet::Module.any_instance.expects(:has_metadata?).returns true
+ Puppet::Module.any_instance.expects(:load_metadata)
+
+ Puppet::Module.new("yay")
+ end
+
+ describe "when loading the medatada file" do
+ confine "Cannot test module metadata without json" => Puppet.features.json?
+
+ before do
+ @data = {
+ :license => "GPL2",
+ :author => "luke",
+ :version => "1.0",
+ :source => "http://foo/",
+ :puppetversion => "0.25"
+ }
+ @text = @data.to_json
+
+ @module = Puppet::Module.new("foo")
+ @module.stubs(:metadata_file).returns "/my/file"
+ File.stubs(:read).with("/my/file").returns @text
+ end
+
+ %w{source author version license}.each do |attr|
+ it "should set #{attr} if present in the metadata file" do
+ @module.load_metadata
+ @module.send(attr).should == @data[attr.to_sym]
+ end
+
+ it "should fail if #{attr} is not present in the metadata file" do
+ @data.delete(attr.to_sym)
+ @text = @data.to_json
+ File.stubs(:read).with("/my/file").returns @text
+ lambda { @module.load_metadata }.should raise_error(Puppet::Module::MissingMetadata)
+ end
+ end
+
+ it "should set puppetversion if present in the metadata file" do
+ @module.load_metadata
+ @module.puppetversion.should == @data[:puppetversion]
+ end
+
+
+ it "should fail if the discovered name is different than the metadata name"
+ end
+end
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list