0001-Fixes-1553-Puppet-and-Facter-cannot-both-install-t.patch
| install.rb | ||
|---|---|---|
| 60 | 60 |
end |
| 61 | 61 | |
| 62 | 62 |
PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi}
|
| 63 |
MIN_FACTER_VERSION = 1.5 |
|
| 63 | 64 | |
| 64 | 65 |
InstallOptions = OpenStruct.new |
| 65 | 66 | |
| ... | ... | |
| 115 | 116 |
PREREQS.each { |pre|
|
| 116 | 117 |
begin |
| 117 | 118 |
require pre |
| 119 |
if pre == "facter" |
|
| 120 |
# to_f isn't quite exact for strings like "1.5.1" but is good |
|
| 121 |
# enough for this purpose. |
|
| 122 |
facter_version = Facter.version.to_f |
|
| 123 |
if facter_version < MIN_FACTER_VERSION |
|
| 124 |
puts "Facter version: %s; minimum required: %s; cannot install" % [facter_version, MIN_FACTER_VERSION] |
|
| 125 |
exit -1 |
|
| 126 |
end |
|
| 127 |
end |
|
| 118 | 128 |
rescue LoadError |
| 119 | 129 |
puts "Could not load %s; cannot install" % pre |
| 120 | 130 |
exit -1 |
| lib/puppet/provider/package/appdmg.rb | ||
|---|---|---|
| 55 | 55 |
self.fail "Mac OS X PKG DMG's must specificy a source string ending in .dmg" |
| 56 | 56 |
end |
| 57 | 57 |
require 'open-uri' |
| 58 |
require 'puppet/util/plist'
|
|
| 58 |
require 'facter/util/plist'
|
|
| 59 | 59 |
cached_source = source |
| 60 | 60 |
if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
|
| 61 | 61 |
cached_source = "/tmp/#{name}"
|
| lib/puppet/provider/package/pkgdmg.rb | ||
|---|---|---|
| 70 | 70 |
self.fail "Mac OS X PKG DMG's must specificy a source string ending in .dmg" |
| 71 | 71 |
end |
| 72 | 72 |
require 'open-uri' |
| 73 |
require 'puppet/util/plist'
|
|
| 73 |
require 'facter/util/plist'
|
|
| 74 | 74 |
cached_source = source |
| 75 | 75 |
if %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ cached_source
|
| 76 | 76 |
cached_source = "/tmp/#{name}"
|
| lib/puppet/util/plist.rb | ||
|---|---|---|
| 1 |
#-- |
|
| 2 |
############################################################## |
|
| 3 |
# Copyright 2006, Ben Bleything <ben@bleything.net> and # |
|
| 4 |
# Patrick May <patrick@hexane.org> # |
|
| 5 |
# # |
|
| 6 |
# Distributed under the MIT license. # |
|
| 7 |
############################################################## |
|
| 8 |
#++ |
|
| 9 |
# = Plist |
|
| 10 |
# |
|
| 11 |
# This is the main file for plist. Everything interesting happens in Plist and Plist::Emit. |
|
| 12 | ||
| 13 |
require 'base64' |
|
| 14 |
require 'cgi' |
|
| 15 |
require 'stringio' |
|
| 16 | ||
| 17 |
require 'puppet/util/plist/generator' |
|
| 18 |
require 'puppet/util/plist/parser' |
|
| 19 | ||
| 20 |
module Plist |
|
| 21 |
VERSION = '3.0.0' |
|
| 22 |
end |
|
| 23 | ||
| lib/puppet/util/plist/generator.rb | ||
|---|---|---|
| 1 |
#--########################################################### |
|
| 2 |
# Copyright 2006, Ben Bleything <ben@bleything.net> and # |
|
| 3 |
# Patrick May <patrick@hexane.org> # |
|
| 4 |
# # |
|
| 5 |
# Distributed under the MIT license. # |
|
| 6 |
############################################################## |
|
| 7 |
#++ |
|
| 8 |
# See Plist::Emit. |
|
| 9 |
module Plist |
|
| 10 |
# === Create a plist |
|
| 11 |
# You can dump an object to a plist in one of two ways: |
|
| 12 |
# |
|
| 13 |
# * <tt>Plist::Emit.dump(obj)</tt> |
|
| 14 |
# * <tt>obj.to_plist</tt> |
|
| 15 |
# * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+. |
|
| 16 |
# |
|
| 17 |
# The following Ruby classes are converted into native plist types: |
|
| 18 |
# Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false |
|
| 19 |
# * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively). |
|
| 20 |
# * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element. |
|
| 21 |
# * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element. |
|
| 22 |
# |
|
| 23 |
# For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below. |
|
| 24 |
module Emit |
|
| 25 |
# Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+. |
|
| 26 |
def to_plist(envelope = true) |
|
| 27 |
return Plist::Emit.dump(self, envelope) |
|
| 28 |
end |
|
| 29 | ||
| 30 |
# Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+. |
|
| 31 |
def save_plist(filename) |
|
| 32 |
Plist::Emit.save_plist(self, filename) |
|
| 33 |
end |
|
| 34 | ||
| 35 |
# The following Ruby classes are converted into native plist types: |
|
| 36 |
# Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time |
|
| 37 |
# |
|
| 38 |
# Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes. |
|
| 39 |
# |
|
| 40 |
# +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+. |
|
| 41 |
# |
|
| 42 |
# The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment. |
|
| 43 |
def self.dump(obj, envelope = true) |
|
| 44 |
output = plist_node(obj) |
|
| 45 | ||
| 46 |
output = wrap(output) if envelope |
|
| 47 | ||
| 48 |
return output |
|
| 49 |
end |
|
| 50 | ||
| 51 |
# Writes the serialized object's plist to the specified filename. |
|
| 52 |
def self.save_plist(obj, filename) |
|
| 53 |
File.open(filename, 'wb') do |f| |
|
| 54 |
f.write(obj.to_plist) |
|
| 55 |
end |
|
| 56 |
end |
|
| 57 | ||
| 58 |
private |
|
| 59 |
def self.plist_node(element) |
|
| 60 |
output = '' |
|
| 61 | ||
| 62 |
if element.respond_to? :to_plist_node |
|
| 63 |
output << element.to_plist_node |
|
| 64 |
else |
|
| 65 |
case element |
|
| 66 |
when Array |
|
| 67 |
if element.empty? |
|
| 68 |
output << "<array/>\n" |
|
| 69 |
else |
|
| 70 |
output << tag('array') {
|
|
| 71 |
element.collect {|e| plist_node(e)}
|
|
| 72 |
} |
|
| 73 |
end |
|
| 74 |
when Hash |
|
| 75 |
if element.empty? |
|
| 76 |
output << "<dict/>\n" |
|
| 77 |
else |
|
| 78 |
inner_tags = [] |
|
| 79 | ||
| 80 |
element.keys.sort.each do |k| |
|
| 81 |
v = element[k] |
|
| 82 |
inner_tags << tag('key', CGI::escapeHTML(k.to_s))
|
|
| 83 |
inner_tags << plist_node(v) |
|
| 84 |
end |
|
| 85 | ||
| 86 |
output << tag('dict') {
|
|
| 87 |
inner_tags |
|
| 88 |
} |
|
| 89 |
end |
|
| 90 |
when true, false |
|
| 91 |
output << "<#{element}/>\n"
|
|
| 92 |
when Time |
|
| 93 |
output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
| 94 |
when Date # also catches DateTime |
|
| 95 |
output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
| 96 |
when String, Symbol, Fixnum, Bignum, Integer, Float |
|
| 97 |
output << tag(element_type(element), CGI::escapeHTML(element.to_s)) |
|
| 98 |
when IO, StringIO |
|
| 99 |
element.rewind |
|
| 100 |
contents = element.read |
|
| 101 |
# note that apple plists are wrapped at a different length then |
|
| 102 |
# what ruby's base64 wraps by default. |
|
| 103 |
# I used #encode64 instead of #b64encode (which allows a length arg) |
|
| 104 |
# because b64encode is b0rked and ignores the length arg. |
|
| 105 |
data = "\n" |
|
| 106 |
Base64::encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
|
|
| 107 |
output << tag('data', data)
|
|
| 108 |
else |
|
| 109 |
output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' ) |
|
| 110 |
data = "\n" |
|
| 111 |
Base64::encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
|
|
| 112 |
output << tag('data', data )
|
|
| 113 |
end |
|
| 114 |
end |
|
| 115 | ||
| 116 |
return output |
|
| 117 |
end |
|
| 118 | ||
| 119 |
def self.comment(content) |
|
| 120 |
return "<!-- #{content} -->\n"
|
|
| 121 |
end |
|
| 122 | ||
| 123 |
def self.tag(type, contents = '', &block) |
|
| 124 |
out = nil |
|
| 125 | ||
| 126 |
if block_given? |
|
| 127 |
out = IndentedString.new |
|
| 128 |
out << "<#{type}>"
|
|
| 129 |
out.raise_indent |
|
| 130 | ||
| 131 |
out << block.call |
|
| 132 | ||
| 133 |
out.lower_indent |
|
| 134 |
out << "</#{type}>"
|
|
| 135 |
else |
|
| 136 |
out = "<#{type}>#{contents.to_s}</#{type}>\n"
|
|
| 137 |
end |
|
| 138 | ||
| 139 |
return out.to_s |
|
| 140 |
end |
|
| 141 | ||
| 142 |
def self.wrap(contents) |
|
| 143 |
output = '' |
|
| 144 | ||
| 145 |
output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n" |
|
| 146 |
output << '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n" |
|
| 147 |
output << '<plist version="1.0">' + "\n" |
|
| 148 | ||
| 149 |
output << contents |
|
| 150 | ||
| 151 |
output << '</plist>' + "\n" |
|
| 152 | ||
| 153 |
return output |
|
| 154 |
end |
|
| 155 | ||
| 156 |
def self.element_type(item) |
|
| 157 |
return case item |
|
| 158 |
when String, Symbol: 'string' |
|
| 159 |
when Fixnum, Bignum, Integer: 'integer' |
|
| 160 |
when Float: 'real' |
|
| 161 |
else |
|
| 162 |
raise "Don't know about this data type... something must be wrong!" |
|
| 163 |
end |
|
| 164 |
end |
|
| 165 |
private |
|
| 166 |
class IndentedString #:nodoc: |
|
| 167 |
attr_accessor :indent_string |
|
| 168 | ||
| 169 |
@@indent_level = 0 |
|
| 170 | ||
| 171 |
def initialize(str = "\t") |
|
| 172 |
@indent_string = str |
|
| 173 |
@contents = '' |
|
| 174 |
end |
|
| 175 | ||
| 176 |
def to_s |
|
| 177 |
return @contents |
|
| 178 |
end |
|
| 179 | ||
| 180 |
def raise_indent |
|
| 181 |
@@indent_level += 1 |
|
| 182 |
end |
|
| 183 | ||
| 184 |
def lower_indent |
|
| 185 |
@@indent_level -= 1 if @@indent_level > 0 |
|
| 186 |
end |
|
| 187 | ||
| 188 |
def <<(val) |
|
| 189 |
if val.is_a? Array |
|
| 190 |
val.each do |f| |
|
| 191 |
self << f |
|
| 192 |
end |
|
| 193 |
else |
|
| 194 |
# if it's already indented, don't bother indenting further |
|
| 195 |
unless val =~ /\A#{@indent_string}/
|
|
| 196 |
indent = @indent_string * @@indent_level |
|
| 197 | ||
| 198 |
@contents << val.gsub(/^/, indent) |
|
| 199 |
else |
|
| 200 |
@contents << val |
|
| 201 |
end |
|
| 202 | ||
| 203 |
# it already has a newline, don't add another |
|
| 204 |
@contents << "\n" unless val =~ /\n$/ |
|
| 205 |
end |
|
| 206 |
end |
|
| 207 |
end |
|
| 208 |
end |
|
| 209 |
end |
|
| 210 | ||
| 211 |
# we need to add this so sorting hash keys works properly |
|
| 212 |
class Symbol #:nodoc: |
|
| 213 |
def <=> (other) |
|
| 214 |
self.to_s <=> other.to_s |
|
| 215 |
end |
|
| 216 |
end |
|
| 217 | ||
| 218 |
class Array #:nodoc: |
|
| 219 |
include Plist::Emit |
|
| 220 |
end |
|
| 221 | ||
| 222 |
class Hash #:nodoc: |
|
| 223 |
include Plist::Emit |
|
| 224 |
end |
|
| 225 | ||
| lib/puppet/util/plist/parser.rb | ||
|---|---|---|
| 1 |
#--########################################################### |
|
| 2 |
# Copyright 2006, Ben Bleything <ben@bleything.net> and # |
|
| 3 |
# Patrick May <patrick@hexane.org> # |
|
| 4 |
# # |
|
| 5 |
# Distributed under the MIT license. # |
|
| 6 |
############################################################## |
|
| 7 |
#++ |
|
| 8 |
# Plist parses Mac OS X xml property list files into ruby data structures. |
|
| 9 |
# |
|
| 10 |
# === Load a plist file |
|
| 11 |
# This is the main point of the library: |
|
| 12 |
# |
|
| 13 |
# r = Plist::parse_xml( filename_or_xml ) |
|
| 14 |
module Plist |
|
| 15 |
# Note that I don't use these two elements much: |
|
| 16 |
# |
|
| 17 |
# + Date elements are returned as DateTime objects. |
|
| 18 |
# + Data elements are implemented as Tempfiles |
|
| 19 |
# |
|
| 20 |
# Plist::parse_xml will blow up if it encounters a data element. |
|
| 21 |
# If you encounter such an error, or if you have a Date element which |
|
| 22 |
# can't be parsed into a Time object, please send your plist file to |
|
| 23 |
# plist@hexane.org so that I can implement the proper support. |
|
| 24 |
def Plist::parse_xml( filename_or_xml ) |
|
| 25 |
listener = Listener.new |
|
| 26 |
#parser = REXML::Parsers::StreamParser.new(File.new(filename), listener) |
|
| 27 |
parser = StreamParser.new(filename_or_xml, listener) |
|
| 28 |
parser.parse |
|
| 29 |
listener.result |
|
| 30 |
end |
|
| 31 | ||
| 32 |
class Listener |
|
| 33 |
#include REXML::StreamListener |
|
| 34 | ||
| 35 |
attr_accessor :result, :open |
|
| 36 | ||
| 37 |
def initialize |
|
| 38 |
@result = nil |
|
| 39 |
@open = Array.new |
|
| 40 |
end |
|
| 41 | ||
| 42 | ||
| 43 |
def tag_start(name, attributes) |
|
| 44 |
@open.push PTag::mappings[name].new |
|
| 45 |
end |
|
| 46 | ||
| 47 |
def text( contents ) |
|
| 48 |
@open.last.text = contents if @open.last |
|
| 49 |
end |
|
| 50 | ||
| 51 |
def tag_end(name) |
|
| 52 |
last = @open.pop |
|
| 53 |
if @open.empty? |
|
| 54 |
@result = last.to_ruby |
|
| 55 |
else |
|
| 56 |
@open.last.children.push last |
|
| 57 |
end |
|
| 58 |
end |
|
| 59 |
end |
|
| 60 | ||
| 61 |
class StreamParser |
|
| 62 |
def initialize( filename_or_xml, listener ) |
|
| 63 |
@filename_or_xml = filename_or_xml |
|
| 64 |
@listener = listener |
|
| 65 |
end |
|
| 66 | ||
| 67 |
TEXT = /([^<]+)/ |
|
| 68 |
XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um |
|
| 69 |
DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um |
|
| 70 |
COMMENT_START = /\A<!--/u |
|
| 71 |
COMMENT_END = /.*?-->/um |
|
| 72 | ||
| 73 | ||
| 74 |
def parse |
|
| 75 |
plist_tags = PTag::mappings.keys.join('|')
|
|
| 76 |
start_tag = /<(#{plist_tags})([^>]*)>/i
|
|
| 77 |
end_tag = /<\/(#{plist_tags})[^>]*>/i
|
|
| 78 | ||
| 79 |
require 'strscan' |
|
| 80 | ||
| 81 |
contents = ( |
|
| 82 |
if (File.exists? @filename_or_xml) |
|
| 83 |
File.open(@filename_or_xml) {|f| f.read}
|
|
| 84 |
else |
|
| 85 |
@filename_or_xml |
|
| 86 |
end |
|
| 87 |
) |
|
| 88 | ||
| 89 |
@scanner = StringScanner.new( contents ) |
|
| 90 |
until @scanner.eos? |
|
| 91 |
if @scanner.scan(COMMENT_START) |
|
| 92 |
@scanner.scan(COMMENT_END) |
|
| 93 |
elsif @scanner.scan(XMLDECL_PATTERN) |
|
| 94 |
elsif @scanner.scan(DOCTYPE_PATTERN) |
|
| 95 |
elsif @scanner.scan(start_tag) |
|
| 96 |
@listener.tag_start(@scanner[1], nil) |
|
| 97 |
if (@scanner[2] =~ /\/$/) |
|
| 98 |
@listener.tag_end(@scanner[1]) |
|
| 99 |
end |
|
| 100 |
elsif @scanner.scan(TEXT) |
|
| 101 |
@listener.text(@scanner[1]) |
|
| 102 |
elsif @scanner.scan(end_tag) |
|
| 103 |
@listener.tag_end(@scanner[1]) |
|
| 104 |
else |
|
| 105 |
raise "Unimplemented element" |
|
| 106 |
end |
|
| 107 |
end |
|
| 108 |
end |
|
| 109 |
end |
|
| 110 | ||
| 111 |
class PTag |
|
| 112 |
@@mappings = { }
|
|
| 113 |
def PTag::mappings |
|
| 114 |
@@mappings |
|
| 115 |
end |
|
| 116 | ||
| 117 |
def PTag::inherited( sub_class ) |
|
| 118 |
key = sub_class.to_s.downcase |
|
| 119 |
key.gsub!(/^plist::/, '' ) |
|
| 120 |
key.gsub!(/^p/, '') unless key == "plist" |
|
| 121 | ||
| 122 |
@@mappings[key] = sub_class |
|
| 123 |
end |
|
| 124 | ||
| 125 |
attr_accessor :text, :children |
|
| 126 |
def initialize |
|
| 127 |
@children = Array.new |
|
| 128 |
end |
|
| 129 | ||
| 130 |
def to_ruby |
|
| 131 |
raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}"
|
|
| 132 |
end |
|
| 133 |
end |
|
| 134 | ||
| 135 |
class PList < PTag |
|
| 136 |
def to_ruby |
|
| 137 |
children.first.to_ruby if children.first |
|
| 138 |
end |
|
| 139 |
end |
|
| 140 | ||
| 141 |
class PDict < PTag |
|
| 142 |
def to_ruby |
|
| 143 |
dict = Hash.new |
|
| 144 |
key = nil |
|
| 145 | ||
| 146 |
children.each do |c| |
|
| 147 |
if key.nil? |
|
| 148 |
key = c.to_ruby |
|
| 149 |
else |
|
| 150 |
dict[key] = c.to_ruby |
|
| 151 |
key = nil |
|
| 152 |
end |
|
| 153 |
end |
|
| 154 | ||
| 155 |
dict |
|
| 156 |
end |
|
| 157 |
end |
|
| 158 | ||
| 159 |
class PKey < PTag |
|
| 160 |
def to_ruby |
|
| 161 |
CGI::unescapeHTML(text || '') |
|
| 162 |
end |
|
| 163 |
end |
|
| 164 | ||
| 165 |
class PString < PTag |
|
| 166 |
def to_ruby |
|
| 167 |
CGI::unescapeHTML(text || '') |
|
| 168 |
end |
|
| 169 |
end |
|
| 170 | ||
| 171 |
class PArray < PTag |
|
| 172 |
def to_ruby |
|
| 173 |
children.collect do |c| |
|
| 174 |
c.to_ruby |
|
| 175 |
end |
|
| 176 |
end |
|
| 177 |
end |
|
| 178 | ||
| 179 |
class PInteger < PTag |
|
| 180 |
def to_ruby |
|
| 181 |
text.to_i |
|
| 182 |
end |
|
| 183 |
end |
|
| 184 | ||
| 185 |
class PTrue < PTag |
|
| 186 |
def to_ruby |
|
| 187 |
true |
|
| 188 |
end |
|
| 189 |
end |
|
| 190 | ||
| 191 |
class PFalse < PTag |
|
| 192 |
def to_ruby |
|
| 193 |
false |
|
| 194 |
end |
|
| 195 |
end |
|
| 196 | ||
| 197 |
class PReal < PTag |
|
| 198 |
def to_ruby |
|
| 199 |
text.to_f |
|
| 200 |
end |
|
| 201 |
end |
|
| 202 | ||
| 203 |
require 'date' |
|
| 204 |
class PDate < PTag |
|
| 205 |
def to_ruby |
|
| 206 |
DateTime.parse(text) |
|
| 207 |
end |
|
| 208 |
end |
|
| 209 | ||
| 210 |
require 'base64' |
|
| 211 |
class PData < PTag |
|
| 212 |
def to_ruby |
|
| 213 |
data = Base64.decode64(text.gsub(/\s+/, '')) |
|
| 214 | ||
| 215 |
begin |
|
| 216 |
return Marshal.load(data) |
|
| 217 |
rescue Exception => e |
|
| 218 |
io = StringIO.new |
|
| 219 |
io.write data |
|
| 220 |
io.rewind |
|
| 221 |
return io |
|
| 222 |
end |
|
| 223 |
end |
|
| 224 |
end |
|
| 225 |
end |
|
| 226 | ||
| 227 |
- |
|