[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35
test branch
puppet-dev at googlegroups.com
Wed Jul 14 10:31:48 UTC 2010
The following commit has been merged in the upstream branch:
commit e5a78009f6bd593e7e3957f0dadb470e623396dd
Author: Jesse Wolfe <jes5199 at gmail.com>
Date: Mon Mar 15 14:16:09 2010 -0700
Feature #3347 REST-ified FileBucket
FileBucket Files have been reimplemented as an indirector terminus so that
they can be transmitted over REST.
The old Network::Client.dipper has been replaced with a compatibility later
in FileBucket::Dipper that uses the indirector to access filebucket termini.
Slightly revised patch:
* No longer allows nil contents in FileBucket outside of initialization
* Uses File.exist? instead of the deprecated File.exists?
* Tweaks JSON serialization and de-serialization to include "path"
Deferred issues:
* Feature #3371 "FileBucket should not keep files in memory".
* Feature #3372 "Replace FileBucket Dipper with more idiomatic calls"
diff --git a/ext/nagios/naggen b/ext/nagios/naggen
index 6ff09e2..a9e04c4 100755
--- a/ext/nagios/naggen
+++ b/ext/nagios/naggen
@@ -178,7 +178,7 @@ class NagiosWriter
def initialize(nagios_type)
@nagios_type = nagios_type
- @bucket = Puppet::Network::Client.client(:Dipper).new(:Path => Puppet[:clientbucketdir])
+ @bucket = Puppet::FileBucket::Dipper.new(:Path => Puppet[:clientbucketdir])
end
def rails_resources
diff --git a/ext/puppet-test b/ext/puppet-test
index dbbde40..5333307 100755
--- a/ext/puppet-test
+++ b/ext/puppet-test
@@ -286,7 +286,7 @@ end
Suite.new :filebucket, "Filebucket interactions" do
def prepare
require 'tempfile'
- @client = Puppet::Network::Client.dipper.new($args)
+ @client = Puppet::FileBucket::Dipper.new($args)
end
newtest :backup, "Backed up file" do
diff --git a/lib/puppet.rb b/lib/puppet.rb
index 1fa51c3..0904f04 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -157,6 +157,7 @@ require 'puppet/ssl'
require 'puppet/module'
require 'puppet/util/storage'
require 'puppet/status'
+require 'puppet/file_bucket/file'
if Puppet[:storeconfigs]
require 'puppet/rails'
diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/application/filebucket.rb
index 0723054..09aaf2b 100644
--- a/lib/puppet/application/filebucket.rb
+++ b/lib/puppet/application/filebucket.rb
@@ -1,6 +1,6 @@
require 'puppet'
require 'puppet/application'
-require 'puppet/network/client'
+require 'puppet/file_bucket/dipper'
Puppet::Application.new(:filebucket) do
@@ -70,10 +70,10 @@ Puppet::Application.new(:filebucket) do
begin
if options[:local] or options[:bucket]
path = options[:bucket] || Puppet[:bucketdir]
- @client = Puppet::Network::Client.dipper.new(:Path => path)
+ @client = Puppet::FileBucket::Dipper.new(:Path => path)
else
require 'puppet/network/handler'
- @client = Puppet::Network::Client.dipper.new(:Server => Puppet[:server])
+ @client = Puppet::FileBucket::Dipper.new(:Server => Puppet[:server])
end
rescue => detail
$stderr.puts detail
@@ -84,4 +84,5 @@ Puppet::Application.new(:filebucket) do
end
end
-end
\ No newline at end of file
+end
+
diff --git a/lib/puppet/application/server.rb b/lib/puppet/application/server.rb
index afdad54..7aeb6ad 100644
--- a/lib/puppet/application/server.rb
+++ b/lib/puppet/application/server.rb
@@ -81,7 +81,6 @@ Puppet::Application.new(:server) do
require 'etc'
require 'puppet/file_serving/content'
require 'puppet/file_serving/metadata'
- require 'puppet/checksum'
xmlrpc_handlers = [:Status, :FileServer, :Master, :Report, :Filebucket]
diff --git a/lib/puppet/checksum.rb b/lib/puppet/checksum.rb
deleted file mode 100644
index 27f08aa..0000000
--- a/lib/puppet/checksum.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Created by Luke Kanies on 2007-9-22.
-# Copyright (c) 2007. All rights reserved.
-
-require 'puppet'
-require 'puppet/util/checksums'
-require 'puppet/indirector'
-
-# A checksum class to model translating checksums to file paths. This
-# is the new filebucket.
-class Puppet::Checksum
- include Puppet::Util::Checksums
-
- extend Puppet::Indirector
-
- indirects :checksum
-
- attr_reader :algorithm, :content
-
- def algorithm=(value)
- unless respond_to?(value)
- raise ArgumentError, "Checksum algorithm %s is not supported" % value
- end
- value = value.intern if value.is_a?(String)
- @algorithm = value
- # Reset the checksum so it's forced to be recalculated.
- @checksum = nil
- end
-
- # Calculate (if necessary) and return the checksum
- def checksum
- unless @checksum
- @checksum = send(algorithm, content)
- end
- @checksum
- end
-
- def initialize(content, algorithm = "md5")
- raise ArgumentError.new("You must specify the content") unless content
-
- @content = content
-
- # Init to avoid warnings.
- @checksum = nil
-
- self.algorithm = algorithm
- end
-
- # This is here so the Indirector::File terminus works correctly.
- def name
- checksum
- end
-
- def to_s
- "Checksum<{%s}%s>" % [algorithm, checksum]
- end
-end
diff --git a/lib/puppet/file_bucket.rb b/lib/puppet/file_bucket.rb
new file mode 100644
index 0000000..881c81e
--- /dev/null
+++ b/lib/puppet/file_bucket.rb
@@ -0,0 +1,4 @@
+# stub
+module Puppet::FileBucket
+ class BucketError < RuntimeError; end
+end
diff --git a/lib/puppet/network/client/dipper.rb b/lib/puppet/file_bucket/dipper.rb
similarity index 59%
rename from lib/puppet/network/client/dipper.rb
rename to lib/puppet/file_bucket/dipper.rb
index 0e2dc14..c73d763 100644
--- a/lib/puppet/network/client/dipper.rb
+++ b/lib/puppet/file_bucket/dipper.rb
@@ -1,32 +1,47 @@
-# The client class for filebuckets.
-class Puppet::Network::Client::Dipper < Puppet::Network::Client
- @handler = Puppet::Network::Handler.handler(:filebucket)
- @drivername = :Bucket
+require 'puppet/file_bucket'
+require 'puppet/file_bucket/file'
+require 'puppet/indirector/request'
+
+class Puppet::FileBucket::Dipper
+ # This is a transitional implementation that uses REST
+ # to access remote filebucket files.
attr_accessor :name
# Create our bucket client
def initialize(hash = {})
+ # Emulate the XMLRPC client
+ server = hash[:Server]
+ port = hash[:Port] || Puppet[:masterport]
+ environment = Puppet[:environment]
+
if hash.include?(:Path)
- bucket = self.class.handler.new(:Path => hash[:Path])
- hash.delete(:Path)
- hash[:Bucket] = bucket
+ @local_path = hash[:Path]
+ @rest_path = nil
+ else
+ @local_path = nil
+ @rest_path = "https://#{server}:#{port}/#{environment}/file_bucket_file/"
end
+ end
- super(hash)
+ def local?
+ !! @local_path
end
# Back up a file to our bucket
def backup(file)
- unless FileTest.exists?(file)
+ unless ::File.exist?(file)
raise(ArgumentError, "File %s does not exist" % file)
end
contents = ::File.read(file)
- unless local?
- contents = Base64.encode64(contents)
- end
begin
- return @driver.addfile(contents,file)
+ file_bucket_file = Puppet::FileBucket::File.new(contents, :bucket_path => @local_path, :path => file)
+ dest_path = "#{@rest_path}#{file_bucket_file.name}"
+
+ request = Puppet::Indirector::Request.new(:file_bucket_file, :save, dest_path)
+
+ file_bucket_file.save(request)
+ return file_bucket_file.checksum_data
rescue => detail
puts detail.backtrace if Puppet[:trace]
raise Puppet::Error, "Could not back up %s: %s" % [file, detail]
@@ -35,13 +50,10 @@ class Puppet::Network::Client::Dipper < Puppet::Network::Client
# Retrieve a file by sum.
def getfile(sum)
- if newcontents = @driver.getfile(sum)
- unless local?
- newcontents = Base64.decode64(newcontents)
- end
- return newcontents
- end
- return nil
+ source_path = "#{@rest_path}md5/#{sum}"
+ file_bucket_file = Puppet::FileBucket::File.find(source_path)
+
+ return file_bucket_file.to_s
end
# Restore the file
diff --git a/lib/puppet/file_bucket/file.rb b/lib/puppet/file_bucket/file.rb
new file mode 100644
index 0000000..7122bfb
--- /dev/null
+++ b/lib/puppet/file_bucket/file.rb
@@ -0,0 +1,123 @@
+require 'puppet/file_bucket'
+require 'puppet/indirector'
+
+class Puppet::FileBucket::File
+ # This class handles the abstract notion of a file in a filebucket.
+ # There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
+ # There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
+ extend Puppet::Indirector
+ require 'puppet/file_bucket/file/indirection_hooks'
+ indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
+
+ attr :path, true
+ attr :paths, true
+ attr :contents, true
+ attr :checksum_type
+ attr :bucket_path
+
+ def self.default_checksum_type
+ :md5
+ end
+
+ def initialize( contents, options = {} )
+ @contents = contents
+ @bucket_path = options[:bucket_path]
+ @path = options[:path]
+ @paths = options[:paths] || []
+ @checksum = options[:checksum]
+ @checksum_type = options[:checksum_type] || self.class.default_checksum_type
+
+ yield(self) if block_given?
+
+ validate!
+ end
+
+ def validate!
+ digest_class( @checksum_type ) # raises error on bad types
+ raise ArgumentError, 'contents must be a string' unless @contents.is_a?(String)
+ validate_checksum(@checksum) if @checksum
+ end
+
+ def contents=(contents)
+ raise "You may not change the contents of a FileBucket File" if @contents
+ @contents = contents
+ end
+
+ def checksum=(checksum)
+ validate_checksum(checksum)
+ self.checksum_type = checksum # this grabs the prefix only
+ @checksum = checksum
+ end
+
+ def validate_checksum(new_checksum)
+ unless new_checksum == checksum_of_type(new_checksum)
+ raise Puppet::Error, "checksum does not match contents"
+ end
+ end
+
+ def checksum
+ @checksum ||= checksum_of_type(checksum_type)
+ end
+
+ def checksum_of_type( type )
+ type = checksum_type( type ) # strip out data segment if there is one
+ type.to_s + ":" + digest_class(type).hexdigest(@contents)
+ end
+
+ def checksum_type=( new_checksum_type )
+ @checksum = nil
+ @checksum_type = checksum_type(new_checksum_type)
+ end
+
+ def checksum_type(checksum = @checksum_type)
+ checksum.to_s.split(':',2)[0].to_sym
+ end
+
+ def checksum_data(new_checksum = self.checksum)
+ new_checksum.split(':',2)[1]
+ end
+
+ def checksum_data=(new_data)
+ self.checksum = "#{checksum_type}:#{new_data}"
+ end
+
+ def digest_class(type = nil)
+ case checksum_type(type)
+ when :md5 : require 'digest/md5' ; Digest::MD5
+ when :sha1 : require 'digest/sha1' ; Digest::SHA1
+ else
+ raise ArgumentError, "not a known checksum type: #{checksum_type(type)}"
+ end
+ end
+
+ def to_s
+ contents
+ end
+
+ def name
+ [checksum_type, checksum_data, path].compact.join('/')
+ end
+
+ def name=(name)
+ self.checksum_type, self.checksum_data, self.path = name.split('/',3)
+ end
+
+ def conflict_check?
+ true
+ end
+
+ def self.from_s( contents )
+ self.new( contents )
+ end
+
+ def to_pson
+ hash = { "contents" => contents }
+ hash["path"] = @path if @path
+ hash.to_pson
+ end
+
+ def self.from_pson( pson )
+ self.new( pson["contents"], :path => pson["path"] )
+ end
+
+end
diff --git a/lib/puppet/file_bucket/file/indirection_hooks.rb b/lib/puppet/file_bucket/file/indirection_hooks.rb
new file mode 100644
index 0000000..ec2bb34
--- /dev/null
+++ b/lib/puppet/file_bucket/file/indirection_hooks.rb
@@ -0,0 +1,10 @@
+require 'puppet/file_bucket/file'
+
+# This module is used to pick the appropriate terminus
+# in filebucket indirections.
+module Puppet::FileBucket::File::IndirectionHooks
+ def select_terminus(request)
+ return :rest if request.protocol == 'https'
+ return Puppet::FileBucket::File.indirection.terminus_class
+ end
+end
diff --git a/lib/puppet/indirector/file_bucket_file/file.rb b/lib/puppet/indirector/file_bucket_file/file.rb
new file mode 100644
index 0000000..ec02ca0
--- /dev/null
+++ b/lib/puppet/indirector/file_bucket_file/file.rb
@@ -0,0 +1,142 @@
+require 'puppet/indirector/code'
+require 'puppet/file_bucket/file'
+
+module Puppet::FileBucketFile
+ class File < Puppet::Indirector::Code
+ desc "Store files in a directory set based on their checksums."
+
+ def initialize
+ Puppet.settings.use(:filebucket)
+ end
+
+ def find( request )
+ checksum, path = request_to_checksum_and_path( request )
+ return find_by_checksum( checksum )
+ end
+
+ def save( request )
+ checksum, path = request_to_checksum_and_path( request )
+
+ instance = request.instance
+ instance.checksum = checksum if checksum
+ instance.path = path if path
+
+ save_to_disk(instance)
+ instance.to_s
+ end
+
+ private
+
+ def find_by_checksum( checksum )
+ model.new( nil, :checksum => checksum ) do |bucket_file|
+ filename = contents_path_for bucket_file
+
+ if ! ::File.exist? filename
+ return nil
+ end
+
+ begin
+ contents = ::File.read filename
+ Puppet.info "FileBucket read #{bucket_file.checksum}"
+ rescue RuntimeError => e
+ raise Puppet::Error, "file could not be read: #{e.message}"
+ end
+
+ if ::File.exist?(paths_path_for bucket_file)
+ ::File.open(paths_path_for bucket_file) do |f|
+ bucket_file.paths = f.readlines.map { |l| l.chomp }
+ end
+ end
+
+ bucket_file.contents = contents
+ end
+ end
+
+ def save_to_disk( bucket_file )
+ # If the file already exists, just return the md5 sum.
+ if ::File.exist?(contents_path_for bucket_file)
+ verify_identical_file!(bucket_file)
+ else
+ # Make the directories if necessary.
+ unless ::File.directory?(path_for bucket_file)
+ Puppet::Util.withumask(0007) do
+ ::FileUtils.mkdir_p(path_for bucket_file)
+ end
+ end
+
+ Puppet.info "FileBucket adding #{bucket_file.path} (#{bucket_file.checksum_data})"
+
+ # Write the file to disk.
+ Puppet::Util.withumask(0007) do
+ ::File.open(contents_path_for(bucket_file), ::File::WRONLY|::File::CREAT, 0440) do |of|
+ of.print bucket_file.contents
+ end
+ end
+ end
+
+ save_path_to_paths_file(bucket_file)
+ return bucket_file.checksum_data
+ end
+
+ def request_to_checksum_and_path( request )
+ checksum_type, checksum, path = request.key.split(/[:\/]/, 3)
+ return nil if checksum_type.to_s == ""
+ return [ checksum_type + ":" + checksum, path ]
+ end
+
+ def path_for(bucket_file, subfile = nil)
+ bucket_path = bucket_file.bucket_path || Puppet[:bucketdir]
+ digest = bucket_file.checksum_data
+
+ dir = ::File.join(digest[0..7].split(""))
+ basedir = ::File.join(bucket_path, dir, digest)
+
+ return basedir unless subfile
+ return ::File.join(basedir, subfile)
+ end
+
+ def contents_path_for(bucket_file)
+ path_for(bucket_file, "contents")
+ end
+
+ def paths_path_for(bucket_file)
+ path_for(bucket_file, "paths")
+ end
+
+ def content_check?
+ true
+ end
+
+ # If conflict_check is enabled, verify that the passed text is
+ # the same as the text in our file.
+ def verify_identical_file!(bucket_file)
+ return unless content_check?
+ disk_contents = ::File.read(contents_path_for(bucket_file))
+
+ # If the contents don't match, then we've found a conflict.
+ # Unlikely, but quite bad.
+ if disk_contents != bucket_file.contents
+ raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}", caller
+ else
+ Puppet.info "FileBucket got a duplicate file #{bucket_file.path} (#{bucket_file.checksum})"
+ end
+ end
+
+ def save_path_to_paths_file(bucket_file)
+ return unless bucket_file.path
+
+ # check for dupes
+ if ::File.exist?(paths_path_for bucket_file)
+ ::File.open(paths_path_for bucket_file) do |f|
+ return if f.readlines.collect { |l| l.chomp }.include?(bucket_file.path)
+ end
+ end
+
+ # if it's a new file, or if our path isn't in the file yet, add it
+ ::File.open(paths_path_for(bucket_file), ::File::WRONLY|::File::CREAT|::File::APPEND) do |of|
+ of.puts bucket_file.path
+ end
+ end
+
+ end
+end
diff --git a/lib/puppet/indirector/file_bucket_file/rest.rb b/lib/puppet/indirector/file_bucket_file/rest.rb
new file mode 100644
index 0000000..15e4f33
--- /dev/null
+++ b/lib/puppet/indirector/file_bucket_file/rest.rb
@@ -0,0 +1,8 @@
+require 'puppet/indirector/rest'
+require 'puppet/file_bucket/file'
+
+module Puppet::FileBucketFile
+ class Rest < Puppet::Indirector::REST
+ desc "This is a REST based mechanism to send/retrieve file to/from the filebucket"
+ end
+end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index d762701..3c64146 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -116,8 +116,14 @@ class Puppet::Indirector::Indirection
end
# Set up our request object.
- def request(method, key, arguments = nil)
- Puppet::Indirector::Request.new(self.name, method, key, arguments)
+ def request(method, instance_or_key, request_or_options = {})
+ if request_or_options.is_a? Puppet::Indirector::Request
+ request = request_or_options
+ request.instance = instance_or_key
+ request.method = method
+ return request
+ end
+ Puppet::Indirector::Request.new(self.name, method, instance_or_key, request_or_options)
end
# Return the singleton terminus for this indirection.
@@ -248,8 +254,8 @@ class Puppet::Indirector::Indirection
# Save the instance in the appropriate terminus. This method is
# normally an instance method on the indirected class.
- def save(instance, *args)
- request = request(:save, instance, *args)
+ def save(instance, request_or_options = nil)
+ request = request(:save, instance, request_or_options)
terminus = prepare(request)
result = terminus.save(request)
diff --git a/lib/puppet/indirector/request.rb b/lib/puppet/indirector/request.rb
index d9e66cb..14608d0 100644
--- a/lib/puppet/indirector/request.rb
+++ b/lib/puppet/indirector/request.rb
@@ -180,6 +180,14 @@ class Puppet::Indirector::Request
end
@protocol = uri.scheme
- @key = URI.unescape(uri.path.sub(/^\//, ''))
+
+ if uri.scheme == 'puppet'
+ @key = URI.unescape(uri.path.sub(/^\//, ''))
+ return
+ end
+
+ env, indirector, @key = URI.unescape(uri.path.sub(/^\//, '')).split('/',3)
+ @key ||= ''
+ self.environment = env unless env == ''
end
end
diff --git a/lib/puppet/network/handler/filebucket.rb b/lib/puppet/network/handler/filebucket.rb
index 4973886..bea1c85 100755
--- a/lib/puppet/network/handler/filebucket.rb
+++ b/lib/puppet/network/handler/filebucket.rb
@@ -3,7 +3,6 @@ require 'digest/md5'
require 'puppet/external/base64'
class Puppet::Network::Handler # :nodoc:
- class BucketError < RuntimeError; end
# Accept files and store them by md5 sum, returning the md5 sum back
# to the client. Alternatively, accept an md5 sum and return the
# associated content.
@@ -19,53 +18,8 @@ class Puppet::Network::Handler # :nodoc:
Puppet::Util.logmethods(self, true)
attr_reader :name, :path
- # this doesn't work for relative paths
- def self.oldpaths(base,md5)
- return [
- File.join(base, md5),
- File.join(base, md5, "contents"),
- File.join(base, md5, "paths")
- ]
- end
-
- # this doesn't work for relative paths
- def self.paths(base,md5)
- dir = File.join(md5[0..7].split(""))
- basedir = File.join(base, dir, md5)
- return [
- basedir,
- File.join(basedir, "contents"),
- File.join(basedir, "paths")
- ]
- end
-
- # Should we check each file as it comes in to make sure the md5
- # sums match? Defaults to false.
- def conflict_check?
- @confictchk
- end
-
def initialize(hash)
- if hash.include?(:ConflictCheck)
- @conflictchk = hash[:ConflictCheck]
- hash.delete(:ConflictCheck)
- else
- @conflictchk = false
- end
-
- if hash.include?(:Path)
- @path = hash[:Path]
- hash.delete(:Path)
- else
- if defined? Puppet
- @path = Puppet[:bucketdir]
- else
- @path = File.expand_path("~/.filebucket")
- end
- end
-
- Puppet.settings.use(:filebucket)
-
+ @path = hash[:Path] || Puppet[:bucketdir]
@name = "Filebucket[#{@path}]"
end
@@ -75,60 +29,14 @@ class Puppet::Network::Handler # :nodoc:
if client
contents = Base64.decode64(contents)
end
- md5 = Digest::MD5.hexdigest(contents)
-
- bpath, bfile, pathpath = FileBucket.paths(@path,md5)
-
- # If the file already exists, just return the md5 sum.
- if FileTest.exists?(bfile)
- # If verification is enabled, then make sure the text matches.
- if conflict_check?
- verify(contents, md5, bfile)
- end
- return md5
- end
-
- # Make the directories if necessary.
- unless FileTest.directory?(bpath)
- Puppet::Util.withumask(0007) do
- FileUtils.mkdir_p(bpath)
- end
- end
-
- # Write the file to disk.
- msg = "Adding %s(%s)" % [path, md5]
- msg += " from #{client}" if client
- self.info msg
-
- # ...then just create the file
- Puppet::Util.withumask(0007) do
- File.open(bfile, File::WRONLY|File::CREAT, 0440) { |of|
- of.print contents
- }
- end
-
- # Write the path to the paths file.
- add_path(path, pathpath)
-
- return md5
+ bucket = Puppet::FileBucket::File.new(contents)
+ return bucket.save
end
# Return the contents associated with a given md5 sum.
def getfile(md5, client = nil, clientip = nil)
- bpath, bfile, bpaths = FileBucket.paths(@path,md5)
-
- unless FileTest.exists?(bfile)
- # Try the old flat style.
- bpath, bfile, bpaths = FileBucket.oldpaths(@path,md5)
- unless FileTest.exists?(bfile)
- return false
- end
- end
-
- contents = nil
- File.open(bfile) { |of|
- contents = of.read
- }
+ bucket = Puppet::FileBucket::File.find("md5:#{md5}")
+ contents = bucket.contents
if client
return Base64.encode64(contents)
@@ -137,46 +45,9 @@ class Puppet::Network::Handler # :nodoc:
end
end
- def paths(md5)
- self.class(@path, md5)
- end
-
def to_s
self.name
end
-
- private
-
- # Add our path to the paths file if necessary.
- def add_path(path, file)
- if FileTest.exists?(file)
- File.open(file) { |of|
- return if of.readlines.collect { |l| l.chomp }.include?(path)
- }
- end
-
- # if it's a new file, or if our path isn't in the file yet, add it
- File.open(file, File::WRONLY|File::CREAT|File::APPEND) { |of|
- of.puts path
- }
- end
-
- # If conflict_check is enabled, verify that the passed text is
- # the same as the text in our file.
- def verify(content, md5, bfile)
- curfile = File.read(bfile)
-
- # If the contents don't match, then we've found a conflict.
- # Unlikely, but quite bad.
- if curfile != contents
- raise(BucketError,
- "Got passed new contents for sum %s" % md5, caller)
- else
- msg = "Got duplicate %s(%s)" % [path, md5]
- msg += " from #{client}" if client
- self.info msg
- end
- end
end
end
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 444fbf7..01ca650 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -165,7 +165,7 @@ module Puppet::Network::HTTP::Handler
# LAK:NOTE This has to be here for testing; it's a stub-point so
# we keep infinite recursion from happening.
def save_object(ind_request, object)
- object.save(ind_request.to_hash)
+ object.save(ind_request)
end
def get?(request)
diff --git a/lib/puppet/type/filebucket.rb b/lib/puppet/type/filebucket.rb
index 468f926..4754e9f 100755
--- a/lib/puppet/type/filebucket.rb
+++ b/lib/puppet/type/filebucket.rb
@@ -1,5 +1,5 @@
module Puppet
- require 'puppet/network/client'
+ require 'puppet/file_bucket/dipper'
newtype(:filebucket) do
@doc = "A repository for backing up files. If no filebucket is
@@ -83,7 +83,7 @@ module Puppet
end
begin
- @bucket = Puppet::Network::Client.client(:Dipper).new(args)
+ @bucket = Puppet::FileBucket::Dipper.new(args)
rescue => detail
puts detail.backtrace if Puppet[:trace]
self.fail("Could not create %s filebucket: %s" % [type, detail])
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index 3d7190c..830f476 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -215,7 +215,7 @@ Puppet::Type.newtype(:tidy) do
super
# only allow backing up into filebuckets
- unless self[:backup].is_a? Puppet::Network::Client.dipper
+ unless self[:backup].is_a? Puppet::FileBucket::Dipper
self[:backup] = false
end
end
diff --git a/spec/integration/checksum.rb b/spec/integration/checksum.rb
deleted file mode 100755
index 49ae8d2..0000000
--- a/spec/integration/checksum.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Luke Kanies on 2007-9-22.
-# Copyright (c) 2007. All rights reserved.
-
-require File.dirname(__FILE__) + '/../spec_helper'
-
-require 'puppet/checksum'
-
-describe Puppet::Checksum, " when using the file terminus" do
- before do
- Puppet.settings.stubs(:use)
- Puppet::Checksum.terminus_class = :file
- @content = "this is some content"
- @sum = Puppet::Checksum.new(@content)
-
- @file = Puppet::Checksum.indirection.terminus.path(@sum.checksum)
- end
-
- it "should store content at a path determined by its checksum" do
- File.stubs(:directory?).returns(true)
- filehandle = mock 'filehandle'
- filehandle.expects(:print).with(@content)
- File.expects(:open).with(@file, "w").yields(filehandle)
-
- @sum.save
- end
-
- it "should retrieve stored content when the checksum is provided as the key" do
- File.stubs(:exist?).returns(true)
- File.expects(:read).with(@file).returns(@content)
-
- newsum = Puppet::Checksum.find(@sum.checksum)
-
- newsum.content.should == @content
- end
-
- it "should remove specified files when asked" do
- File.stubs(:exist?).returns(true)
- File.expects(:unlink).with(@file)
-
- Puppet::Checksum.destroy(@sum.name)
- end
-
- after do
- Puppet.settings.clear
- end
-end
diff --git a/spec/integration/indirector/certificate/rest.rb b/spec/integration/indirector/bucket_file/rest.rb
old mode 100755
new mode 100644
similarity index 71%
copy from spec/integration/indirector/certificate/rest.rb
copy to spec/integration/indirector/bucket_file/rest.rb
index 8042f86..296b03e
--- a/spec/integration/indirector/certificate/rest.rb
+++ b/spec/integration/indirector/bucket_file/rest.rb
@@ -2,11 +2,11 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-require 'puppet/ssl/certificate'
+require 'puppet/file_bucket/file'
require 'puppet/network/server'
require 'puppet/network/http/webrick/rest'
-describe "Certificate REST Terminus" do
+describe "Filebucket REST Terminus" do
before do
Puppet[:masterport] = 34343
Puppet[:server] = "localhost"
@@ -34,20 +34,21 @@ describe "Certificate REST Terminus" do
@host = Puppet::SSL::Host.new(Puppet[:certname])
- @params = { :port => 34343, :handlers => [ :certificate ] }
+ @params = { :port => 34343, :handlers => [ :file_bucket_file ] }
@server = Puppet::Network::Server.new(@params)
@server.listen
- # Then switch to a remote CA, so that we go through REST.
- Puppet::SSL::Host.ca_location = :remote
+ @old_terminus = Puppet::FileBucket::File.indirection.terminus_class
+ Puppet::FileBucket::File.terminus_class = :rest
# LAK:NOTE We need to have a fake model here so that our indirected methods get
# passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
# return.
- @mock_model = stub('faked model', :name => "certificate")
+ @file_bucket_file = stub_everything 'file_bucket_file'
+ @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file)
Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
- Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
end
after do
@@ -55,14 +56,13 @@ describe "Certificate REST Terminus" do
Puppet::SSL::Host.ca_location = :none
Puppet.settings.clear
@server.unlisten
+ Puppet::FileBucket::File.terminus_class = @old_terminus
end
- it "should be able to retrieve a remote certificate" do
- @mock_model.expects(:find).returns @host.certificate
- result = Puppet::SSL::Certificate.find('bar')
+ it "should be able save a file to the remote filebucket" do
+ @file_bucket_file.expects(:save)
- # There's no good '==' method on certs.
- result.content.to_s.should == @host.certificate.content.to_s
- result.name.should == "bar"
+ file_bucket_file = Puppet::FileBucket::File.new("pouet")
+ file_bucket_file.save()
end
end
diff --git a/spec/integration/network/client.rb b/spec/integration/network/client.rb
index 9707637..fe1524e 100755
--- a/spec/integration/network/client.rb
+++ b/spec/integration/network/client.rb
@@ -5,7 +5,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/network/client'
describe Puppet::Network::Client do
- %w{ca dipper file report resource runner status}.each do |name|
+ %w{ca file report resource runner status}.each do |name|
it "should have a #{name} client" do
Puppet::Network::Client.client(name).should be_instance_of(Class)
end
diff --git a/spec/unit/application/filebucket.rb b/spec/unit/application/filebucket.rb
index e87bab4..f78c0b7 100644
--- a/spec/unit/application/filebucket.rb
+++ b/spec/unit/application/filebucket.rb
@@ -43,7 +43,7 @@ describe "Filebucket" do
Puppet.stubs(:settraps)
Puppet::Log.stubs(:level=)
Puppet.stubs(:parse_config)
- Puppet::Network::Client.dipper.stubs(:new)
+ Puppet::FileBucket::Dipper.stubs(:new)
@filebucket.options.stubs(:[]).with(any_parameters)
end
@@ -106,15 +106,15 @@ describe "Filebucket" do
it "should create a client with the default bucket if none passed" do
Puppet.stubs(:[]).with(:bucketdir).returns("path")
- Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Path] == "path" }
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
@filebucket.run_setup
end
- it "should create a local Client dipper with the given bucket" do
+ it "should create a local Dipper with the given bucket" do
@filebucket.options.stubs(:[]).with(:bucket).returns("path")
- Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Path] == "path" }
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Path] == "path" }
@filebucket.run_setup
end
@@ -126,7 +126,7 @@ describe "Filebucket" do
it "should create a remote Client to the configured server" do
Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com")
- Puppet::Network::Client::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" }
+ Puppet::FileBucket::Dipper.expects(:new).with { |h| h[:Server] == "puppet.reductivelabs.com" }
@filebucket.run_setup
end
@@ -142,11 +142,11 @@ describe "Filebucket" do
Puppet.stubs(:settraps)
Puppet::Log.stubs(:level=)
Puppet.stubs(:parse_config)
- Puppet::Network::Client.dipper.stubs(:new)
+ Puppet::FileBucket::Dipper.stubs(:new)
@filebucket.options.stubs(:[]).with(any_parameters)
@client = stub 'client'
- Puppet::Network::Client::Dipper.stubs(:new).returns(@client)
+ Puppet::FileBucket::Dipper.stubs(:new).returns(@client)
@filebucket.run_setup
end
diff --git a/spec/unit/application/main.rb b/spec/unit/application/main.rb
index 74c40c1..ea8c43f 100755
--- a/spec/unit/application/main.rb
+++ b/spec/unit/application/main.rb
@@ -53,7 +53,7 @@ describe "Puppet" do
Puppet.stubs(:trap)
Puppet::Log.stubs(:level=)
Puppet.stubs(:parse_config)
- Puppet::Network::Client.dipper.stubs(:new)
+ Puppet::FileBucket::Dipper.stubs(:new)
STDIN.stubs(:read)
@main.options.stubs(:[]).with(any_parameters)
diff --git a/spec/unit/file_bucket/file.rb b/spec/unit/file_bucket/file.rb
new file mode 100644
index 0000000..76f8e25
--- /dev/null
+++ b/spec/unit/file_bucket/file.rb
@@ -0,0 +1,239 @@
+#!/usr/bin/env ruby
+
+require ::File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/file_bucket/file'
+require 'digest/md5'
+require 'digest/sha1'
+
+describe Puppet::FileBucket::File do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "md5:4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
+ end
+
+ it "should save a file" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+ ::File.expects(:directory?).with(@dir).returns false
+ ::FileUtils.expects(:mkdir_p).with(@dir)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+
+ bucketfile = Puppet::FileBucket::File.new(@contents)
+ bucketfile.save
+
+ end
+
+ describe "using the indirector's find method" do
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ bucketfile = Puppet::FileBucket::File.find("md5:#{@digest}")
+ bucketfile.should == nil
+ end
+
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
+
+ bucketfile = Puppet::FileBucket::File.find("md5:#{@digest}")
+ bucketfile.should_not == nil
+ end
+
+ describe "using RESTish digest notation" do
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
+ bucketfile.should == nil
+ end
+
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
+
+ bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
+ bucketfile.should_not == nil
+ end
+
+ end
+ end
+
+ it "should have a to_s method to return the contents" do
+ Puppet::FileBucket::File.new(@contents).to_s.should == @contents
+ end
+
+ it "should have a method that returns the digest algorithm" do
+ Puppet::FileBucket::File.new(@contents, :checksum => @checksum).checksum_type.should == :md5
+ end
+
+ it "should allow contents to be specified in a block" do
+ bucket = Puppet::FileBucket::File.new(nil) do |fb|
+ fb.contents = "content"
+ end
+ bucket.contents.should == "content"
+ end
+
+ it "should raise an error if changing content" do
+ x = Puppet::FileBucket::File.new("first")
+ proc { x.contents = "new" }.should raise_error
+ end
+
+ it "should require contents to be a string" do
+ proc { Puppet::FileBucket::File.new(5) }.should raise_error(ArgumentError)
+ end
+
+ it "should raise an error if setting contents to a non-string" do
+ proc do
+ Puppet::FileBucket::File.new(nil) do |x|
+ x.contents = 5
+ end
+ end.should raise_error(ArgumentError)
+ end
+
+ it "should set the contents appropriately" do
+ Puppet::FileBucket::File.new(@contents).contents.should == @contents
+ end
+
+ it "should calculate the checksum" do
+ Digest::MD5.expects(:hexdigest).with(@contents).returns('mychecksum')
+ Puppet::FileBucket::File.new(@contents).checksum.should == 'md5:mychecksum'
+ end
+
+ it "should remove the old checksum value if the algorithm is changed" do
+ Digest::MD5.expects(:hexdigest).with(@contents).returns('oldsum')
+ sum = Puppet::FileBucket::File.new(@contents)
+ oldsum = sum.checksum
+
+ sum.checksum_type = :sha1
+ Digest::SHA1.expects(:hexdigest).with(@contents).returns('newsum')
+ sum.checksum.should == 'sha1:newsum'
+ end
+
+ it "should default to 'md5' as the checksum algorithm if the algorithm is not in the name" do
+ Puppet::FileBucket::File.new(@contents).checksum_type.should == :md5
+ end
+
+ it "should support specifying the checksum_type during initialization" do
+ sum = Puppet::FileBucket::File.new(@contents, :checksum_type => :sha1)
+ sum.checksum_type.should == :sha1
+ end
+
+ it "should fail when an unsupported checksum_type is used" do
+ proc { Puppet::FileBucket::File.new(@contents, :checksum_type => :nope) }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if given an invalid checksum at initialization" do
+ proc { Puppet::FileBucket::File.new(@contents, :checksum => "md5:00000000000000000000000000000000") }.should raise_error(RuntimeError)
+ end
+
+ it "should fail if assigned an invalid checksum " do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ proc { bucket.checksum = "md5:00000000000000000000000000000000" }.should raise_error(RuntimeError)
+ end
+
+ it "should accept checksum_data without a prefix" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ bucket.checksum_data = @digest
+ end
+
+
+ describe "when using back-ends" do
+ it "should redirect using Puppet::Indirector" do
+ Puppet::Indirector::Indirection.instance(:file_bucket_file).model.should equal(Puppet::FileBucket::File)
+ end
+
+ it "should have a :save instance method" do
+ Puppet::FileBucket::File.new("mysum").should respond_to(:save)
+ end
+
+ it "should respond to :find" do
+ Puppet::FileBucket::File.should respond_to(:find)
+ end
+
+ it "should respond to :destroy" do
+ Puppet::FileBucket::File.should respond_to(:destroy)
+ end
+ end
+
+ describe "when saving files" do
+ it "should save the contents to the calculated path" do
+ ::File.stubs(:directory?).with(@dir).returns(true)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ mockfile = mock "file"
+ mockfile.expects(:print).with(@contents)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
+
+ Puppet::FileBucket::File.new(@contents).save
+ end
+
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ ::File.umask == 0007 and arg == @dir
+ end
+ ::File.expects(:directory?).with(@dir).returns(false)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ Puppet::FileBucket::File.new(@contents).save
+ end
+ end
+
+ it "should accept a path" do
+ remote_path = '/path/on/the/remote/box'
+ Puppet::FileBucket::File.new(@contents, :path => remote_path).path.should == remote_path
+ end
+
+ it "should append the path to the paths file" do
+ remote_path = '/path/on/the/remote/box'
+
+ ::File.expects(:directory?).with(@dir).returns(true)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ mockfile = mock "file"
+ mockfile.expects(:puts).with('/path/on/the/remote/box')
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:open).with("#{@dir}/paths", ::File::WRONLY|::File::CREAT|::File::APPEND).yields mockfile
+ Puppet::FileBucket::File.new(@contents, :path => remote_path).save
+
+ end
+
+ it "should return a url-ish name" do
+ Puppet::FileBucket::File.new(@contents).name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ end
+
+ it "should reject a url-ish name with an invalid checksum" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ lambda { bucket.name = "sha1/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/new/path" }.should raise_error
+ end
+
+ it "should accept a url-ish name" do
+ bucket = Puppet::FileBucket::File.new(@contents)
+ lambda { bucket.name = "sha1/034fa2ed8e211e4d20f20e792d777f4a30af1a93/new/path" }.should_not raise_error
+ bucket.checksum_type.should == :sha1
+ bucket.checksum_data.should == '034fa2ed8e211e4d20f20e792d777f4a30af1a93'
+ bucket.path.should == "new/path"
+ end
+
+ it "should return a url-ish name with a path" do
+ Puppet::FileBucket::File.new(@contents, :path => 'my/path').name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/my/path"
+ end
+
+ it "should convert the contents to PSON" do
+ Puppet::FileBucket::File.new(@contents).to_pson.should == '{"contents":"file contents"}'
+ end
+
+ it "should load from PSON" do
+ Puppet::FileBucket::File.from_pson({"contents"=>"file contents"}).contents.should == "file contents"
+ end
+
+end
diff --git a/spec/unit/indirector/file_bucket_file/file.rb b/spec/unit/indirector/file_bucket_file/file.rb
new file mode 100755
index 0000000..0df530d
--- /dev/null
+++ b/spec/unit/indirector/file_bucket_file/file.rb
@@ -0,0 +1,288 @@
+#!/usr/bin/env ruby
+
+require ::File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/file_bucket_file/file'
+
+describe Puppet::FileBucketFile::File do
+ it "should be a subclass of the Code terminus class" do
+ Puppet::FileBucketFile::File.superclass.should equal(Puppet::Indirector::Code)
+ end
+
+ it "should have documentation" do
+ Puppet::FileBucketFile::File.doc.should be_instance_of(String)
+ end
+
+ describe "when initializing" do
+ it "should use the filebucket settings section" do
+ Puppet.settings.expects(:use).with(:filebucket)
+ Puppet::FileBucketFile::File.new
+ end
+ end
+
+
+ describe "the find_by_checksum method" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "md5:4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
+ end
+
+ it "should return nil if a file doesn't exist" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "md5:#{@digest}")
+ bucketfile.should == nil
+ end
+
+ it "should find a filebucket if the file exists" do
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns false
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
+
+ bucketfile = Puppet::FileBucketFile::File.new.send(:find_by_checksum, "md5:#{@digest}")
+ bucketfile.should_not == nil
+ end
+
+ it "should load the paths" do
+ paths = ["path1", "path2"]
+ ::File.expects(:exist?).with("#{@dir}/contents").returns true
+ ::File.expects(:exist?).with("#{@dir}/paths").returns true
+ ::File.expects(:read).with("#{@dir}/contents").returns @contents
+
+ mockfile = mock "file"
+ mockfile.expects(:readlines).returns( paths )
+ ::File.expects(:open).with("#{@dir}/paths").yields mockfile
+
+ Puppet::FileBucketFile::File.new.send(:find_by_checksum, "md5:#{@digest}").paths.should == paths
+ end
+
+ end
+
+ describe "when retrieving files" do
+ before :each do
+ Puppet.settings.stubs(:use)
+ @store = Puppet::FileBucketFile::File.new
+
+ @digest = "70924d6fa4b2d745185fa4660703a5c0"
+ @sum = stub 'sum', :name => @digest
+
+ @dir = "/what/ever"
+
+ Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
+
+ @contents_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/contents'
+ @paths_path = '/what/ever/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
+
+ @request = stub 'request', :key => "md5/#{@digest}/remote/path"
+ end
+
+ it "should call find_by_checksum" do
+ @store.expects(:find_by_checksum).with("md5:#{@digest}").returns(false)
+ @store.find(@request)
+ end
+
+ it "should look for the calculated path" do
+ ::File.expects(:exist?).with(@contents_path).returns(false)
+ @store.find(@request)
+ end
+
+ it "should return an instance of Puppet::FileBucket::File created with the content if the file exists" do
+ content = "my content"
+ bucketfile = stub 'bucketfile'
+ bucketfile.stubs(:bucket_path)
+ bucketfile.stubs(:checksum_data).returns(@digest)
+ bucketfile.stubs(:checksum).returns(@checksum)
+
+ bucketfile.expects(:contents=).with(content)
+ Puppet::FileBucket::File.expects(:new).with(nil, {:checksum => "md5:#{@digest}"}).yields(bucketfile).returns(bucketfile)
+
+ ::File.expects(:exist?).with(@contents_path).returns(true)
+ ::File.expects(:exist?).with(@paths_path).returns(false)
+ ::File.expects(:read).with(@contents_path).returns(content)
+
+ @store.find(@request).should equal(bucketfile)
+ end
+
+ it "should return nil if no file is found" do
+ ::File.expects(:exist?).with(@contents_path).returns(false)
+ @store.find(@request).should be_nil
+ end
+
+ it "should fail intelligently if a found file cannot be read" do
+ ::File.expects(:exist?).with(@contents_path).returns(true)
+ ::File.expects(:read).with(@contents_path).raises(RuntimeError)
+ proc { @store.find(@request) }.should raise_error(Puppet::Error)
+ end
+
+ end
+
+ describe "when determining file paths" do
+ before do
+ Puppet[:bucketdir] = '/dev/null/bucketdir'
+ @digest = 'DEADBEEFC0FFEE'
+ @bucket = stub_everything "bucket"
+ @bucket.expects(:checksum_data).returns(@digest)
+ end
+
+ it "should use the value of the :bucketdir setting as the root directory" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ path.should =~ %r{^/dev/null/bucketdir}
+ end
+
+ it "should choose a path 8 directories deep with each directory name being the respective character in the filebucket" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ dirs = @digest[0..7].split("").join(File::SEPARATOR)
+ path.should be_include(dirs)
+ end
+
+ it "should use the full filebucket as the final directory name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ ::File.basename(::File.dirname(path)).should == @digest
+ end
+
+ it "should use 'contents' as the actual file name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ ::File.basename(path).should == "contents"
+ end
+
+ it "should use the bucketdir, the 8 sum character directories, the full filebucket, and 'contents' as the full file name" do
+ path = Puppet::FileBucketFile::File.new.send(:contents_path_for, @bucket)
+ path.should == ['/dev/null/bucketdir', @digest[0..7].split(""), @digest, "contents"].flatten.join(::File::SEPARATOR)
+ end
+ end
+
+ describe "when saving files" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "md5:4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
+
+ @bucket = stub "bucket file"
+ @bucket.stubs(:bucket_path)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ @bucket.stubs(:path).returns(nil)
+ @bucket.stubs(:contents).returns("file contents")
+ end
+
+ it "should save the contents to the calculated path" do
+ ::File.stubs(:directory?).with(@dir).returns(true)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ mockfile = mock "file"
+ mockfile.expects(:print).with(@contents)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
+
+ Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
+ end
+
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ ::File.umask == 0007 and arg == @dir
+ end
+ ::File.expects(:directory?).with(@dir).returns(false)
+ ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
+ ::File.expects(:exist?).with("#{@dir}/contents").returns false
+
+ Puppet::FileBucketFile::File.new.send(:save_to_disk, @bucket)
+ end
+ end
+
+
+ describe "when verifying identical files" do
+ before do
+ # this is the default from spec_helper, but it keeps getting reset at odd times
+ Puppet[:bucketdir] = "/dev/null/bucket"
+
+ @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @checksum = "md5:4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
+ @dir = '/dev/null/bucket/4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0'
+
+ @contents = "file contents"
+
+ @bucket = stub "bucket file"
+ @bucket.stubs(:bucket_path)
+ @bucket.stubs(:checksum).returns(@checksum)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ @bucket.stubs(:path).returns(nil)
+ @bucket.stubs(:contents).returns("file contents")
+ end
+
+ it "should raise an error if the files don't match" do
+ File.expects(:read).with("#{@dir}/contents").returns("corrupt contents")
+ lambda{ Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket) }.should raise_error(Puppet::FileBucket::BucketError)
+ end
+
+ it "should do nothing if the files match" do
+ File.expects(:read).with("#{@dir}/contents").returns("file contents")
+ Puppet::FileBucketFile::File.new.send(:verify_identical_file!, @bucket)
+ end
+
+ end
+
+
+ describe "when writing to the paths file" do
+ before do
+ Puppet[:bucketdir] = '/dev/null/bucketdir'
+ @digest = '70924d6fa4b2d745185fa4660703a5c0'
+ @bucket = stub_everything "bucket"
+
+ @paths_path = '/dev/null/bucketdir/7/0/9/2/4/d/6/f/70924d6fa4b2d745185fa4660703a5c0/paths'
+
+ @paths = []
+ @bucket.stubs(:paths).returns(@paths)
+ @bucket.stubs(:checksum_data).returns(@digest)
+ end
+
+ it "should create a file if it doesn't exist" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(false)
+ file = stub "file"
+ file.expects(:puts).with('path/to/save')
+ File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
+
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
+
+ it "should append to a file if it exists" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(true)
+ old_file = stub "file"
+ old_file.stubs(:readlines).returns []
+ File.expects(:open).with(@paths_path).yields(old_file)
+
+ file = stub "file"
+ file.expects(:puts).with('path/to/save')
+ File.expects(:open).with(@paths_path, ::File::WRONLY|::File::CREAT|::File::APPEND).yields(file)
+
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
+
+ it "should not alter a file if it already contains the path" do
+ @bucket.expects(:path).returns('path/to/save').at_least_once
+ File.expects(:exist?).with(@paths_path).returns(true)
+ old_file = stub "file"
+ old_file.stubs(:readlines).returns ["path/to/save\n"]
+ File.expects(:open).with(@paths_path).yields(old_file)
+
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
+
+ it "should do nothing if there is no path" do
+ @bucket.expects(:path).returns(nil).at_least_once
+
+ Puppet::FileBucketFile::File.new.send(:save_path_to_paths_file, @bucket)
+ end
+ end
+
+end
diff --git a/spec/unit/indirector/status/rest.rb b/spec/unit/indirector/file_bucket_file/rest.rb
similarity index 57%
copy from spec/unit/indirector/status/rest.rb
copy to spec/unit/indirector/file_bucket_file/rest.rb
index 8f803a2..3aacd3c 100755
--- a/spec/unit/indirector/status/rest.rb
+++ b/spec/unit/indirector/file_bucket_file/rest.rb
@@ -2,10 +2,10 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-require 'puppet/indirector/status/rest'
+require 'puppet/indirector/file_bucket_file/rest'
-describe Puppet::Indirector::Status::Rest do
+describe Puppet::FileBucketFile::Rest do
it "should be a sublcass of Puppet::Indirector::REST" do
- Puppet::Indirector::Status::Rest.superclass.should equal(Puppet::Indirector::REST)
+ Puppet::FileBucketFile::Rest.superclass.should equal(Puppet::Indirector::REST)
end
end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index ca2a412..02d04a3 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -198,8 +198,8 @@ describe Puppet::Indirector::Indirection do
@indirection.request(:funtest, "yayness", :one => :two)
end
- it "should default to the arguments being nil" do
- Puppet::Indirector::Request.expects(:new).with { |name, method, key, args| args.nil? }
+ it "should default to the arguments being empty" do
+ Puppet::Indirector::Request.expects(:new).with { |name, method, key, args| args == {} }
@indirection.request(:funtest, "yayness")
end
diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb
index 848a608..b885779 100755
--- a/spec/unit/indirector/request.rb
+++ b/spec/unit/indirector/request.rb
@@ -132,8 +132,8 @@ describe Puppet::Indirector::Request do
Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff").port.should == 80
end
- it "should set the request key to the unescaped unqualified path from the URI" do
- Puppet::Indirector::Request.new(:ind, :method, "http:///stuff with spaces").key.should == "stuff with spaces"
+ it "should set the request key to the unescaped key part path from the URI" do
+ Puppet::Indirector::Request.new(:ind, :method, "http://host/environment/terminus/stuff with spaces").key.should == "stuff with spaces"
end
it "should set the :uri attribute to the full URI" do
diff --git a/spec/unit/network/client/dipper.rb b/spec/unit/network/client/dipper.rb
index d1631fb..7d8b3da 100755
--- a/spec/unit/network/client/dipper.rb
+++ b/spec/unit/network/client/dipper.rb
@@ -2,15 +2,109 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-describe Puppet::Network::Client.dipper do
+require 'puppet/file_bucket/dipper'
+describe Puppet::FileBucket::Dipper do
it "should fail in an informative way when there are failures backing up to the server" do
- FileTest.stubs(:exists?).returns true
+ File.stubs(:exists?).returns true
File.stubs(:read).returns "content"
- @dipper = Puppet::Network::Client::Dipper.new(:Path => "/my/bucket")
+ @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket")
- @dipper.driver.expects(:addfile).raises ArgumentError
+ filemock = stub "bucketfile"
+ Puppet::FileBucket::File.stubs(:new).returns(filemock)
+ filemock.expects(:name).returns "name"
+ filemock.expects(:save).raises ArgumentError
lambda { @dipper.backup("/my/file") }.should raise_error(Puppet::Error)
end
+
+ it "should backup files to a local bucket" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Path => "/my/bucket"
+ )
+
+ File.stubs(:exists?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
+
+ req = stub "req"
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:name).returns('md5/DIGEST123')
+ bucketfile.stubs(:checksum_data).returns("DIGEST123")
+ bucketfile.expects(:save).with(req)
+
+ Puppet::FileBucket::File.stubs(:new).with(
+ "my contents",
+ :bucket_path => '/my/bucket',
+ :path => '/my/file'
+ ).returns(bucketfile)
+
+ Puppet::Indirector::Request.stubs(:new).with(:file_bucket_file, :save, 'md5/DIGEST123').returns(req)
+
+ @dipper.backup("/my/file").should == "DIGEST123"
+ end
+
+ it "should retrieve files from a local bucket" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Path => "/my/bucket"
+ )
+
+ File.stubs(:exists?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
+
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:to_s).returns "Content"
+
+ Puppet::FileBucket::File.expects(:find).with(
+ 'md5/DIGEST123'
+ ).returns(bucketfile)
+
+ @dipper.getfile("DIGEST123").should == "Content"
+ end
+
+ it "should backup files to a remote server" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Server => "puppetmaster",
+ :Port => "31337"
+ )
+
+ File.stubs(:exists?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
+
+ req = stub "req"
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:name).returns('md5/DIGEST123')
+ bucketfile.stubs(:checksum_data).returns("DIGEST123")
+ bucketfile.expects(:save).with(req)
+
+ Puppet::FileBucket::File.stubs(:new).with(
+ "my contents",
+ :bucket_path => nil,
+ :path => '/my/file'
+ ).returns(bucketfile)
+
+ Puppet::Indirector::Request.stubs(:new).with(:file_bucket_file, :save, 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123').returns(req)
+
+ @dipper.backup("/my/file").should == "DIGEST123"
+ end
+
+ it "should retrieve files from a remote server" do
+ @dipper = Puppet::FileBucket::Dipper.new(
+ :Server => "puppetmaster",
+ :Port => "31337"
+ )
+
+ File.stubs(:exists?).returns true
+ File.stubs(:read).with("/my/file").returns "my contents"
+
+ bucketfile = stub "bucketfile"
+ bucketfile.stubs(:to_s).returns "Content"
+
+ Puppet::FileBucket::File.expects(:find).with(
+ 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123'
+ ).returns(bucketfile)
+
+ @dipper.getfile("DIGEST123").should == "Content"
+ end
+
+
end
diff --git a/spec/unit/network/http/handler.rb b/spec/unit/network/http/handler.rb
index 5598121..2218a0a 100755
--- a/spec/unit/network/http/handler.rb
+++ b/spec/unit/network/http/handler.rb
@@ -402,10 +402,7 @@ describe Puppet::Network::HTTP::Handler do
end
it "should use a common method for determining the request parameters" do
- @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy)
- @model_instance.expects(:save).with do |args|
- args[:foo] == :baz and args[:bar] == :xyzzy
- end
+ @model_instance.expects(:save).with(@irequest)
@handler.do_save(@irequest, @request, @response)
end
diff --git a/spec/unit/other/checksum.rb b/spec/unit/other/checksum.rb
deleted file mode 100755
index 6a63e83..0000000
--- a/spec/unit/other/checksum.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Luke Kanies on 2007-9-22.
-# Copyright (c) 2007. All rights reserved.
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-require 'puppet/checksum'
-
-describe Puppet::Checksum do
- it "should have 'Checksum' and the checksum algorithm when converted to a string" do
- inst = Puppet::Checksum.new("whatever", "md5")
- inst.to_s.should == "Checksum<{md5}#{inst.checksum}>"
- end
-
- it "should convert algorithm names to symbols when they are set after checksum creation" do
- sum = Puppet::Checksum.new("whatever")
- sum.algorithm = "md5"
- sum.algorithm.should == :md5
- end
-
- it "should return the checksum as the name" do
- sum = Puppet::Checksum.new("whatever")
- sum.checksum.should == sum.name
- end
-end
-
-describe Puppet::Checksum, " when initializing" do
- before do
- @content = "this is some content"
- @sum = Puppet::Checksum.new(@content)
- end
-
- it "should require content" do
- proc { Puppet::Checksum.new(nil) }.should raise_error(ArgumentError)
- end
-
- it "should set the content appropriately" do
- @sum.content.should == @content
- end
-
- it "should calculate the checksum" do
- require 'digest/md5'
- Digest::MD5.expects(:hexdigest).with(@content).returns(:mychecksum)
- @sum.checksum.should == :mychecksum
- end
-
- it "should not calculate the checksum until it is asked for" do
- require 'digest/md5'
- Digest::MD5.expects(:hexdigest).never
- sum = Puppet::Checksum.new(@content, :md5)
- end
-
- it "should remove the old checksum value if the algorithm is changed" do
- Digest::MD5.expects(:hexdigest).with(@content).returns(:oldsum)
- oldsum = @sum.checksum
- @sum.algorithm = :sha1
- Digest::SHA1.expects(:hexdigest).with(@content).returns(:newsum)
- @sum.checksum.should == :newsum
- end
-
- it "should default to 'md5' as the checksum algorithm if the algorithm is not in the name" do
- @sum.algorithm.should == :md5
- end
-
- it "should support specifying the algorithm during initialization" do
- sum = Puppet::Checksum.new(@content, :sha1)
- sum.algorithm.should == :sha1
- end
-
- it "should fail when an unsupported algorithm is used" do
- proc { Puppet::Checksum.new(@content, :nope) }.should raise_error(ArgumentError)
- end
-end
-
-describe Puppet::Checksum, " when using back-ends" do
- it "should redirect using Puppet::Indirector" do
- Puppet::Indirector::Indirection.instance(:checksum).model.should equal(Puppet::Checksum)
- end
-
- it "should have a :save instance method" do
- Puppet::Checksum.new("mysum").should respond_to(:save)
- end
-
- it "should respond to :find" do
- Puppet::Checksum.should respond_to(:find)
- end
-
- it "should respond to :destroy" do
- Puppet::Checksum.should respond_to(:destroy)
- end
-end
diff --git a/spec/unit/type/file.rb b/spec/unit/type/file.rb
index afb050a..cedb170 100755
--- a/spec/unit/type/file.rb
+++ b/spec/unit/type/file.rb
@@ -811,7 +811,7 @@ describe Puppet::Type.type(:file) do
it "should be able to use the default filebucket without a catalog" do
file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
- file.bucket.should be_instance_of(Puppet::Network::Client::Dipper)
+ file.bucket.should be_instance_of(Puppet::FileBucket::Dipper)
end
it "should look up the filebucket during finish()" do
diff --git a/spec/unit/type/filebucket.rb b/spec/unit/type/filebucket.rb
index 78bfa36..a0ff45a 100644
--- a/spec/unit/type/filebucket.rb
+++ b/spec/unit/type/filebucket.rb
@@ -55,19 +55,19 @@ describe Puppet::Type.type(:filebucket) do
it "should use any provided path" do
bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => "/foo/bar"
- Puppet::Network::Client.client(:Dipper).expects(:new).with(:Path => "/foo/bar").returns @bucket
+ Puppet::FileBucket::Dipper.expects(:new).with(:Path => "/foo/bar").returns @bucket
bucket.bucket
end
it "should use any provided server and port" do
bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "myserv", :port => "myport", :path => false
- Puppet::Network::Client.client(:Dipper).expects(:new).with(:Server => "myserv", :Port => "myport").returns @bucket
+ Puppet::FileBucket::Dipper.expects(:new).with(:Server => "myserv", :Port => "myport").returns @bucket
bucket.bucket
end
it "should use the default server if the path is unset and no server is provided" do
Puppet.settings[:server] = "myserv"
bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
- Puppet::Network::Client.client(:Dipper).expects(:new).with { |args| args[:Server] == "myserv" }.returns @bucket
+ Puppet::FileBucket::Dipper.expects(:new).with { |args| args[:Server] == "myserv" }.returns @bucket
bucket.bucket
end
end
diff --git a/test/network/client/dipper.rb b/test/network/client/dipper.rb
index 51494be..611ee73 100755
--- a/test/network/client/dipper.rb
+++ b/test/network/client/dipper.rb
@@ -10,7 +10,7 @@ class TestDipperClient < Test::Unit::TestCase
def setup
super
- @dipper = Puppet::Network::Client.dipper.new(:Path => tempfile)
+ @dipper = Puppet::FileBucket::Dipper.new(:Path => tempfile)
end
# Make sure we can create a new file with 'restore'.
diff --git a/test/network/handler/bucket.rb b/test/network/handler/bucket.rb
deleted file mode 100755
index 24e70cf..0000000
--- a/test/network/handler/bucket.rb
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../lib/puppettest'
-
-require 'puppettest'
-require 'puppet/network/handler/filebucket'
-require 'base64'
-require 'mocha'
-
-class TestBucket < Test::Unit::TestCase
- include PuppetTest::ServerTest
-
- def out
- if defined? @num
- @num += 1
- else
- @num = 1
- end
-
- #Puppet.err "#{Process.pid}: %s: %s" % [@num, memory()]
- #gcdebug(String)
- end
-
- # run through all of the files and exercise the filebucket methods
- def checkfiles(client)
- files = filelist()
-
- # iterate across all of the files
- files.each { |file|
- Puppet.warning file
- out
- tempdir = tempfile()
- Dir.mkdir(tempdir)
- name = File.basename(file)
- tmppath = File.join(tempdir,name)
- @@tmpfiles << tmppath
-
- out
- # copy the files to our tmp directory so we can modify them...
- FileUtils.cp(file, tmppath)
-
- # make sure the copy worked
- assert(FileTest.exists?(tmppath))
-
- # backup both the orig file and the tmp file
- osum = nil
- tsum = nil
- nsum = nil
- out
- assert_nothing_raised("Could not back up file") {
- osum = client.backup(file)
- }
- out
- assert_nothing_raised("Could not back up second file") {
- tsum = client.backup(tmppath)
- }
- out
-
- # verify you got the same sum back for both
- assert(tsum == osum)
-
- # modify our tmp file
- unless FileTest.writable?(tmppath)
- File.chmod(0644, tmppath)
- end
- File.open(tmppath,File::WRONLY|File::TRUNC) { |wf|
- wf.print "This is some test text\n"
- }
- out
-
- # back it up
- assert_nothing_raised {
- #STDERR.puts("backing up %s" % tmppath) if $debug
- nsum = client.backup(tmppath)
- }
- out
-
- # and verify the sum changed
- assert(tsum != nsum)
-
- # restore the orig
- assert_nothing_raised {
- nsum = client.restore(tmppath,tsum)
- }
- out
-
- # and verify it actually got restored
- contents = File.open(tmppath) { |rf|
- #STDERR.puts("reading %s" % tmppath) if $debug
- rf.read
- }
- out
- csum = Digest::MD5.hexdigest(contents)
- out
- assert(tsum == csum)
- }
- end
-
- # a list of files that should be on the system
- # just something to test moving files around
- def filelist
- if defined? @files
- return @files
- else
- @files = []
- end
-
- %w{
- who bash sh uname /etc/passwd /etc/syslog.conf /etc/hosts
- }.each { |file|
- # if it's fully qualified, just add it
- if file =~ /^\//
- if FileTest.exists?(file)
- @files.push file
- end
- else
- # else if it's unqualified, look for it in our path
- begin
- path = %x{which #{file}}
- rescue => detail
- #STDERR.puts "Could not search for binaries: %s" % detail
- next
- end
-
- if path != ""
- @files.push path.chomp
- end
- end
- }
-
- return @files
- end
-
- def setup
- super
- @bucket = tempfile()
- end
-
- #def teardown
- # system("lsof -p %s" % Process.pid)
- # super
- #end
-
- # test operating against the local filebucket object
- # this calls the direct server methods, which are different than the
- # Dipper methods
- def test_localserver
- files = filelist()
- server = nil
- assert_nothing_raised {
- server = Puppet::Network::Handler.filebucket.new(
- :Path => @bucket
- )
- }
-
- # iterate across them...
- files.each { |file|
- contents = File.open(file) { |of| of.read }
-
- md5 = nil
-
- # add a file to the repository
- assert_nothing_raised {
- #STDERR.puts("adding %s" % file) if $debug
- md5 = server.addfile(Base64.encode64(contents),file)
- }
-
- # and get it back again
- newcontents = nil
- assert_nothing_raised {
- #STDERR.puts("getting %s" % file) if $debug
- newcontents = Base64.decode64(server.getfile(md5))
- }
-
- # and then make sure they're still the same
- assert(
- contents == newcontents
- )
- }
- end
-
- # test with a server and a Dipper
- def test_localboth
- files = filelist()
-
- bucket = nil
- client = nil
- threads = []
- assert_nothing_raised {
- bucket = Puppet::Network::Handler.filebucket.new(
- :Path => @bucket
- )
- }
-
- #sleep(30)
- assert_nothing_raised {
- client = Puppet::Network::Client.dipper.new(
- :Bucket => bucket
- )
- }
-
- #4.times { checkfiles(client) }
- checkfiles(client)
- end
-
- def test_no_path_duplicates
- bucket = nil
- assert_nothing_raised {
- bucket = Puppet::Network::Handler.filebucket.new(
- :Path => @bucket
- )
- }
-
- sum = nil
- assert_nothing_raised {
- sum = bucket.addfile("yayness", "/my/file")
- }
- assert_nothing_raised {
- bucket.addfile("yayness", "/my/file")
- }
-
- a, b, pathfile = bucket.class.paths(bucket.path, sum)
-
- assert(FileTest.exists?(pathfile), "No path file at %s" % pathfile)
-
- assert_equal("/my/file\n", File.read(pathfile))
- end
-
- # #447 -- a flat file structure just won't suffice.
- def test_deeper_filestructure
- bucket = Puppet::Network::Handler.filebucket.new(:Path => @bucket)
-
- text = "this is some text"
- md5 = Digest::MD5.hexdigest(text)
-
- olddir = File.join(@bucket, md5)
- FileUtils.mkdir_p(olddir)
- oldcontent = File.join(olddir, "contents")
- File.open(oldcontent, "w") { |f| f.print text }
-
- result = nil
- assert_nothing_raised("Could not retrieve content from old structure") do
- result = bucket.getfile(md5)
- end
- assert_equal(text, result, "old-style content is wrong")
-
- text = "and this is some new text"
- md5 = Digest::MD5.hexdigest(text)
-
- dirs = File.join(md5[0..7].split(""))
- dir = File.join(@bucket, dirs, md5)
- filedir, contents, paths = bucket.class.paths(@bucket, md5)
-
- assert_equal(dir, filedir, "did not use a deeper file structure")
- assert_equal(File.join(dir, "contents"), contents,
- "content path is not the deeper version")
- assert_equal(File.join(dir, "paths"), paths,
- "paths file path is not the deeper version")
-
- # Store our new text and make sure it gets stored in the new location
- path = "/some/fake/path"
- assert_nothing_raised("Could not store text") do
- bucket.addfile(text, path)
- end
- assert(FileTest.exists?(contents), "did not create content file")
- assert_equal(text, File.read(contents), "content is not right")
- assert(FileTest.exists?(paths), "did not create paths file")
- assert(File.read(paths).include?(path), "paths file does not contain path")
-
- # And make sure we get it back out again
- assert_nothing_raised("Could not retrieve new-style content") do
- result = bucket.getfile(md5)
- end
- assert_equal(text, result, "did not retrieve new content correctly")
- end
-
- def test_add_path
- bucket = Puppet::Network::Handler.filebucket.new(:Path => @bucket)
-
- file = tempfile()
-
- assert(! FileTest.exists?(file), "file already exists")
-
- path = "/some/thing"
- assert_nothing_raised("Could not add path") do
- bucket.send(:add_path, path, file)
- end
- assert_equal(path + "\n", File.read(file), "path was not added")
-
- assert_nothing_raised("Could not add path second time") do
- bucket.send(:add_path, path, file)
- end
- assert_equal(path + "\n", File.read(file), "path was duplicated")
-
- # Now try a new path
- newpath = "/another/path"
- assert_nothing_raised("Could not add path second time") do
- bucket.send(:add_path, newpath, file)
- end
- text = [path, newpath].join("\n") + "\n"
- assert_equal(text, File.read(file), "path was duplicated")
-
- assert_nothing_raised("Could not add path third time") do
- bucket.send(:add_path, path, file)
- end
- assert_equal(text, File.read(file), "path was duplicated")
- assert_nothing_raised("Could not add second path second time") do
- bucket.send(:add_path, newpath, file)
- end
- assert_equal(text, File.read(file), "path was duplicated")
- end
-end
-
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list