puppet 0.25.0 → 0.25.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (138) hide show
  1. data/CHANGELOG +4772 -19114
  2. data/README +1 -1
  3. data/Rakefile +7 -25
  4. data/{sbin → bin}/puppetca +0 -0
  5. data/{sbin → bin}/puppetd +0 -0
  6. data/{sbin → bin}/puppetmasterd +0 -0
  7. data/{sbin → bin}/puppetqd +0 -0
  8. data/{sbin → bin}/puppetrun +0 -0
  9. data/conf/osx/createpackage.sh +1 -1
  10. data/conf/redhat/client.init +6 -3
  11. data/conf/redhat/puppet.spec +26 -14
  12. data/conf/redhat/server.init +3 -2
  13. data/ext/vim/syntax/puppet.vim +4 -1
  14. data/install.rb +25 -7
  15. data/lib/puppet.rb +1 -1
  16. data/lib/puppet/agent.rb +2 -2
  17. data/lib/puppet/application/puppet.rb +3 -3
  18. data/lib/puppet/application/puppetd.rb +0 -7
  19. data/lib/puppet/application/puppetdoc.rb +1 -0
  20. data/lib/puppet/application/puppetmasterd.rb +2 -2
  21. data/lib/puppet/configurer.rb +6 -1
  22. data/lib/puppet/configurer/fact_handler.rb +2 -2
  23. data/lib/puppet/defaults.rb +2 -2
  24. data/lib/puppet/external/nagios/base.rb +4 -3
  25. data/lib/puppet/external/pson/common.rb +367 -0
  26. data/lib/puppet/external/pson/pure.rb +77 -0
  27. data/lib/puppet/external/pson/pure/generator.rb +429 -0
  28. data/lib/puppet/external/pson/pure/parser.rb +269 -0
  29. data/lib/puppet/external/pson/version.rb +8 -0
  30. data/lib/puppet/feature/pson.rb +6 -0
  31. data/lib/puppet/feature/rails.rb +1 -5
  32. data/lib/puppet/file_serving/configuration.rb +2 -2
  33. data/lib/puppet/indirector/certificate/rest.rb +6 -0
  34. data/lib/puppet/indirector/facts/facter.rb +1 -1
  35. data/lib/puppet/indirector/ldap.rb +1 -1
  36. data/lib/puppet/indirector/queue.rb +3 -3
  37. data/lib/puppet/indirector/rest.rb +1 -1
  38. data/lib/puppet/network/authstore.rb +34 -53
  39. data/lib/puppet/network/formats.rb +59 -9
  40. data/lib/puppet/network/http/mongrel/rest.rb +10 -9
  41. data/lib/puppet/network/http/webrick.rb +8 -1
  42. data/lib/puppet/network/http/webrick/rest.rb +2 -5
  43. data/lib/puppet/network/http_server/webrick.rb +1 -4
  44. data/lib/puppet/parser/ast/leaf.rb +1 -3
  45. data/lib/puppet/parser/collector.rb +14 -8
  46. data/lib/puppet/parser/compiler.rb +7 -0
  47. data/lib/puppet/parser/functions/fqdn_rand.rb +4 -10
  48. data/lib/puppet/parser/functions/regsubst.rb +44 -30
  49. data/lib/puppet/parser/functions/require.rb +18 -3
  50. data/lib/puppet/parser/functions/versioncmp.rb +1 -1
  51. data/lib/puppet/parser/interpreter.rb +1 -1
  52. data/lib/puppet/parser/lexer.rb +29 -31
  53. data/lib/puppet/parser/loaded_code.rb +4 -0
  54. data/lib/puppet/parser/parser_support.rb +5 -2
  55. data/lib/puppet/parser/resource.rb +31 -6
  56. data/lib/puppet/property.rb +3 -2
  57. data/lib/puppet/provider/macauthorization/macauthorization.rb +14 -14
  58. data/lib/puppet/provider/package/dpkg.rb +1 -1
  59. data/lib/puppet/provider/package/portage.rb +15 -5
  60. data/lib/puppet/provider/package/rug.rb +1 -1
  61. data/lib/puppet/provider/package/up2date.rb +1 -1
  62. data/lib/puppet/provider/package/urpmi.rb +1 -1
  63. data/lib/puppet/provider/service/daemontools.rb +7 -10
  64. data/lib/puppet/provider/service/runit.rb +7 -17
  65. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +7 -47
  66. data/lib/puppet/provider/zone/solaris.rb +12 -3
  67. data/lib/puppet/relationship.rb +12 -12
  68. data/lib/puppet/reports/rrdgraph.rb +1 -1
  69. data/lib/puppet/reports/store.rb +2 -2
  70. data/lib/puppet/reports/tagmail.rb +5 -16
  71. data/lib/puppet/resource.rb +15 -20
  72. data/lib/puppet/resource/catalog.rb +40 -29
  73. data/lib/puppet/ssl/certificate_revocation_list.rb +0 -2
  74. data/lib/puppet/ssl/host.rb +2 -3
  75. data/lib/puppet/sslcertificates/ca.rb +0 -5
  76. data/lib/puppet/type/cron.rb +1 -1
  77. data/lib/puppet/type/file/owner.rb +7 -4
  78. data/lib/puppet/type/resources.rb +17 -17
  79. data/lib/puppet/type/yumrepo.rb +10 -3
  80. data/lib/puppet/util.rb +6 -11
  81. data/lib/puppet/util/inifile.rb +8 -0
  82. data/lib/puppet/util/log.rb +2 -2
  83. data/lib/puppet/util/monkey_patches.rb +0 -43
  84. data/lib/puppet/util/{json.rb → pson.rb} +6 -6
  85. data/lib/puppet/util/rdoc.rb +5 -3
  86. data/lib/puppet/util/selinux.rb +12 -6
  87. data/lib/puppet/util/settings.rb +25 -16
  88. data/lib/puppet/util/settings/file_setting.rb +4 -2
  89. data/spec/integration/application/puppet.rb +4 -4
  90. data/spec/integration/defaults.rb +2 -2
  91. data/spec/integration/indirector/catalog/queue.rb +5 -5
  92. data/spec/integration/indirector/certificate/rest.rb +3 -1
  93. data/spec/integration/network/formats.rb +36 -36
  94. data/spec/integration/parser/functions/require.rb +5 -3
  95. data/spec/integration/provider/mailalias/aliases.rb +4 -4
  96. data/spec/integration/resource/catalog.rb +4 -4
  97. data/spec/unit/application/puppet.rb +16 -15
  98. data/spec/unit/application/puppetd.rb +1 -1
  99. data/spec/unit/application/puppetdoc.rb +6 -0
  100. data/spec/unit/application/puppetmasterd.rb +6 -6
  101. data/spec/unit/configurer/fact_handler.rb +3 -3
  102. data/spec/unit/file_serving/configuration.rb +16 -2
  103. data/spec/unit/indirector/certificate/rest.rb +34 -0
  104. data/spec/unit/indirector/queue.rb +15 -15
  105. data/spec/unit/indirector/rest.rb +31 -9
  106. data/spec/unit/network/authstore.rb +105 -26
  107. data/spec/unit/network/formats.rb +124 -39
  108. data/spec/unit/parser/ast/leaf.rb +15 -0
  109. data/spec/unit/parser/collector.rb +20 -9
  110. data/spec/unit/parser/compiler.rb +19 -0
  111. data/spec/unit/parser/functions/fqdn_rand.rb +62 -0
  112. data/spec/unit/parser/functions/regsubst.rb +80 -0
  113. data/spec/unit/parser/functions/require.rb +19 -7
  114. data/spec/unit/parser/interpreter.rb +2 -2
  115. data/spec/unit/parser/lexer.rb +32 -7
  116. data/spec/unit/parser/loaded_code.rb +18 -1
  117. data/spec/unit/parser/parser.rb +10 -2
  118. data/spec/unit/parser/resource.rb +53 -2
  119. data/spec/unit/parser/scope.rb +1 -1
  120. data/spec/unit/property.rb +14 -4
  121. data/spec/unit/provider/package/dpkg.rb +7 -0
  122. data/spec/unit/provider/service/daemontools.rb +19 -2
  123. data/spec/unit/provider/service/redhat.rb +2 -0
  124. data/spec/unit/provider/service/runit.rb +15 -4
  125. data/spec/unit/provider/ssh_authorized_key/parsed.rb +32 -55
  126. data/spec/unit/relationship.rb +21 -46
  127. data/spec/unit/resource.rb +30 -39
  128. data/spec/unit/resource/catalog.rb +66 -51
  129. data/spec/unit/ssl/certificate_revocation_list.rb +0 -12
  130. data/spec/unit/type/cron.rb +33 -0
  131. data/spec/unit/type/file/owner.rb +10 -4
  132. data/spec/unit/util/json.rb +9 -9
  133. data/spec/unit/util/log.rb +36 -0
  134. data/spec/unit/util/settings.rb +6 -0
  135. data/test/data/providers/ssh_authorized_key/parsed/authorized_keys2 +1 -0
  136. data/test/lib/puppettest/support/utils.rb +8 -16
  137. metadata +36 -13
  138. data/lib/puppet/feature/json.rb +0 -2
@@ -26,9 +26,51 @@ Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
26
26
  yaml
27
27
  end
28
28
 
29
- # Everything's supported
29
+ # Everything's supported unless you're on 1.8.1
30
30
  def supported?(klass)
31
- true
31
+ RUBY_VERSION != '1.8.1'
32
+ end
33
+
34
+ # fixup invalid yaml as per:
35
+ # http://redmine.ruby-lang.org/issues/show/1331
36
+ def fixup(yaml)
37
+ yaml.gsub!(/((?:&id\d+\s+)?!ruby\/object:.*?)\s*\?/) { "? #{$1}" }
38
+ yaml
39
+ end
40
+ end
41
+
42
+ # This is a "special" format which is used for the moment only when sending facts
43
+ # as REST GET parameters (see Puppet::Configurer::FactHandler).
44
+ # This format combines a yaml serialization, then zlib compression and base64 encoding.
45
+ Puppet::Network::FormatHandler.create(:b64_zlib_yaml, :mime => "text/b64_zlib_yaml") do
46
+ require 'base64'
47
+ require 'zlib'
48
+
49
+ def intern(klass, text)
50
+ decode(text)
51
+ end
52
+
53
+ def intern_multiple(klass, text)
54
+ decode(text)
55
+ end
56
+
57
+ def render(instance)
58
+ yaml = instance.to_yaml
59
+
60
+ yaml = encode(fixup(yaml)) unless yaml.nil?
61
+ yaml
62
+ end
63
+
64
+ def render_multiple(instances)
65
+ yaml = instances.to_yaml
66
+
67
+ yaml = encode(fixup(yaml)) unless yaml.nil?
68
+ yaml
69
+ end
70
+
71
+ # Because of yaml issue in ruby 1.8.1...
72
+ def supported?(klass)
73
+ RUBY_VERSION != '1.8.1'
32
74
  end
33
75
 
34
76
  # fixup invalid yaml as per:
@@ -37,6 +79,14 @@ Puppet::Network::FormatHandler.create(:yaml, :mime => "text/yaml") do
37
79
  yaml.gsub!(/((?:&id\d+\s+)?!ruby\/object:.*?)\s*\?/) { "? #{$1}" }
38
80
  yaml
39
81
  end
82
+
83
+ def encode(text)
84
+ Base64.encode64(Zlib::Deflate.deflate(text, Zlib::BEST_COMPRESSION))
85
+ end
86
+
87
+ def decode(yaml)
88
+ YAML.load(Zlib::Inflate.inflate(Base64.decode64(yaml)))
89
+ end
40
90
  end
41
91
 
42
92
 
@@ -89,22 +139,22 @@ Puppet::Network::FormatHandler.create(:raw, :mime => "application/x-raw", :weigh
89
139
  end
90
140
  end
91
141
 
92
- Puppet::Network::FormatHandler.create(:json, :mime => "text/json", :weight => 10, :required_methods => [:render_method, :intern_method]) do
93
- confine :true => Puppet.features.json?
142
+ Puppet::Network::FormatHandler.create(:pson, :mime => "text/pson", :weight => 10, :required_methods => [:render_method, :intern_method]) do
143
+ confine :true => Puppet.features.pson?
94
144
 
95
145
  def intern(klass, text)
96
- data_to_instance(klass, JSON.parse(text))
146
+ data_to_instance(klass, PSON.parse(text))
97
147
  end
98
148
 
99
149
  def intern_multiple(klass, text)
100
- JSON.parse(text).collect do |data|
150
+ PSON.parse(text).collect do |data|
101
151
  data_to_instance(klass, data)
102
152
  end
103
153
  end
104
154
 
105
- # JSON monkey-patches Array, so this works.
155
+ # PSON monkey-patches Array, so this works.
106
156
  def render_multiple(instances)
107
- instances.to_json
157
+ instances.to_pson
108
158
  end
109
159
 
110
160
  # If they pass class information, we want to ignore it. By default,
@@ -118,6 +168,6 @@ Puppet::Network::FormatHandler.create(:json, :mime => "text/json", :weight => 10
118
168
  if data.is_a?(klass)
119
169
  return data
120
170
  end
121
- klass.from_json(data)
171
+ klass.from_pson(data)
122
172
  end
123
173
  end
@@ -50,16 +50,17 @@ class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
50
50
 
51
51
  # produce the body of the response
52
52
  def set_response(response, result, status = 200)
53
- args = [status]
54
-
55
53
  # Set the 'reason' (or 'message', as it's called in Webrick), when
56
- # we have a failure.
57
- if status >= 300
58
- args << false << result
59
- end
60
-
61
- response.start(*args) do |head, body|
62
- body.write(result)
54
+ # we have a failure, unless we're on a version of mongrel that doesn't
55
+ # support this.
56
+ if status < 300
57
+ response.start(status) { |head, body| body.write(result) }
58
+ else
59
+ begin
60
+ response.start(status,false,result) { |head, body| body.write(result) }
61
+ rescue ArgumentError
62
+ response.start(status) { |head, body| body.write(result) }
63
+ end
63
64
  end
64
65
  end
65
66
 
@@ -31,13 +31,20 @@ class Puppet::Network::HTTP::WEBrick
31
31
  arguments.merge!(setup_ssl)
32
32
 
33
33
  @server = WEBrick::HTTPServer.new(arguments)
34
+ @server.listeners.each { |l| l.start_immediately = false }
34
35
 
35
36
  setup_handlers
36
37
 
37
38
  @mutex.synchronize do
38
39
  raise "WEBrick server is already listening" if @listening
39
40
  @listening = true
40
- @thread = Thread.new { @server.start }
41
+ @thread = Thread.new {
42
+ @server.start { |sock|
43
+ raise "Client disconnected before connection could be established" unless IO.select([sock],nil,nil,0.1)
44
+ sock.accept
45
+ @server.run(sock)
46
+ }
47
+ }
41
48
  end
42
49
  end
43
50
 
@@ -50,11 +50,8 @@ class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
50
50
 
51
51
  def set_response(response, result, status = 200)
52
52
  response.status = status
53
- if status >= 200 and status < 300
54
- response.body = result
55
- else
56
- response.reason_phrase = result
57
- end
53
+ response.body = result if status >= 200 and status != 304
54
+ response.reason_phrase = result if status < 200 or status >= 300
58
55
  end
59
56
 
60
57
  # Retrieve node/cert/ip information from the request object.
@@ -21,13 +21,10 @@ module Puppet
21
21
  # with them, with flags appropriate for checking client
22
22
  # certificates for revocation
23
23
  def x509store
24
- if Puppet[:cacrl] == 'false'
24
+ unless File.exist?(Puppet[:cacrl])
25
25
  # No CRL, no store needed
26
26
  return nil
27
27
  end
28
- unless File.exist?(Puppet[:cacrl])
29
- raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'false' to disable CRL usage"
30
- end
31
28
  crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
32
29
  store = OpenSSL::X509::Store.new
33
30
  store.purpose = OpenSSL::X509::PURPOSE_ANY
@@ -102,9 +102,7 @@ class Puppet::Parser::AST
102
102
  end
103
103
 
104
104
  def to_classname
105
- classname = @value.to_s.downcase
106
- classname.gsub!(/[^-a-zA-Z0-9:.]/,'') if regex?
107
- classname
105
+ to_s.downcase.gsub(/[^-\w:.]/,'').sub(/^\.+/,'')
108
106
  end
109
107
 
110
108
  # implementing eql? and hash so that when an HostName is stored
@@ -102,18 +102,24 @@ class Puppet::Parser::Collector
102
102
  raise Puppet::DevError, "Cannot collect resources for a nil host" unless @scope.host
103
103
  host = Puppet::Rails::Host.find_by_name(@scope.host)
104
104
 
105
- query = {:include => {:param_values => :param_name}}
106
-
107
105
  search = "(exported=? AND restype=?)"
108
106
  values = [true, @type]
109
107
 
110
108
  search += " AND (%s)" % @equery if @equery
111
109
 
112
- # this is a small performance optimisation
113
- # the tag mechanism involves 3 more joins, which are
114
- # needed only if we query on tags.
115
- if search =~ /puppet_tags/
116
- query[:include][:puppet_tags] = :resource_tags
110
+ # note:
111
+ # we're not eagerly including any relations here because
112
+ # it can creates so much objects we'll throw out later.
113
+ # We used to eagerly include param_names/values but the way
114
+ # the search filter is built ruined those efforts and we
115
+ # were eagerly loading only the searched parameter and not
116
+ # the other ones.
117
+ query = {}
118
+ case search
119
+ when /puppet_tags/
120
+ query = {:joins => {:resource_tags => :puppet_tag}}
121
+ when /param_name/
122
+ query = {:joins => {:param_values => :param_name}}
117
123
  end
118
124
 
119
125
  # We're going to collect objects from rails, but we don't want any
@@ -139,7 +145,7 @@ class Puppet::Parser::Collector
139
145
  # and such, we'll need to vary the conditions, but this works with no
140
146
  # attributes, anyway.
141
147
  time = Puppet::Util.thinmark do
142
- Puppet::Rails::Resource.find(:all, @type, true, query).each do |obj|
148
+ Puppet::Rails::Resource.find(:all, query).each do |obj|
143
149
  if resource = exported_resource(obj)
144
150
  count += 1
145
151
  resources << resource
@@ -415,6 +415,9 @@ class Puppet::Parser::Compiler
415
415
 
416
416
  # local resource array to maintain resource ordering
417
417
  @resources = []
418
+
419
+ # Make sure any external node classes are in our class list
420
+ @catalog.add_class(*@node.classes)
418
421
  end
419
422
 
420
423
  # Set the node's parameters into the top-scope as variables.
@@ -422,6 +425,10 @@ class Puppet::Parser::Compiler
422
425
  node.parameters.each do |param, value|
423
426
  @topscope.setvar(param, value)
424
427
  end
428
+
429
+ # These might be nil.
430
+ catalog.client_version = node.parameters["clientversion"]
431
+ catalog.server_version = node.parameters["serverversion"]
425
432
  end
426
433
 
427
434
  # Return an array of all of the unevaluated resources. These will be definitions,
@@ -1,15 +1,9 @@
1
1
  Puppet::Parser::Functions::newfunction(:fqdn_rand, :type => :rvalue, :doc =>
2
2
  "Generates random numbers based on the node's fqdn. The first argument
3
- sets the range. The second argument specifies a number to add to the
4
- seed and is optional.") do |args|
3
+ sets the range. Additional (optional) arguments may be used to further
4
+ distinguish the seed.") do |args|
5
5
  require 'md5'
6
- max = args[0]
7
- if args[1] then
8
- seed = args[1]
9
- else
10
- seed = 1
11
- end
12
- fqdn_seed = MD5.new(lookupvar('fqdn')).to_s.hex
13
- srand(seed+fqdn_seed)
6
+ max = args.shift
7
+ srand MD5.new([lookupvar('fqdn'),args].join(':')).to_s.hex
14
8
  rand(max).to_s
15
9
  end
@@ -1,22 +1,22 @@
1
1
  module Puppet::Parser::Functions
2
2
  newfunction(:regsubst, :type => :rvalue,
3
3
  :doc => "
4
- Perform regexp replacement on a string.
4
+ Perform regexp replacement on a string or array of strings.
5
5
 
6
6
  - **Parameters** (in order):
7
7
 
8
- :str: The string to operate on.
8
+ :target: The string or array of strings to operate on. If an array, the replacement will be performed on each of the elements in the array, and the return value will be an array.
9
9
 
10
- :regexp: The regular expression matching the string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
10
+ :regexp: The regular expression matching the target string. If you want it anchored at the start and or end of the string, you must do that with ^ and $ yourself.
11
11
 
12
- :replacement: Replacement string. Can contain back references to what was matched using 0, 1, and so on.
12
+ :replacement: Replacement string. Can contain back references to what was matched using \\0, \\1, and so on.
13
13
 
14
14
  :flags: Optional. String of single letter flags for how the regexp is interpreted:
15
15
 
16
16
  - **E** Extended regexps
17
17
  - **I** Ignore case in regexps
18
18
  - **M** Multiline regexps
19
- - **G** Global replacement; all occurrences of the regexp in the string will be replaced. Without this, only the first occurrence will be replaced.
19
+ - **G** Global replacement; all occurrences of the regexp in each target string will be replaced. Without this, only the first occurrence will be replaced.
20
20
 
21
21
  :lang: Optional. How to handle multibyte characters. A single-character string with the following values:
22
22
 
@@ -35,36 +35,50 @@ Put angle brackets around each octet in the node's IP address::
35
35
 
36
36
  $x = regsubst($ipaddress, '([0-9]+)', '<\\1>', 'G')
37
37
  ") \
38
- do |args|
39
- flag_mapping = {
40
- "E" => Regexp::EXTENDED,
41
- "I" => Regexp::IGNORECASE,
42
- "M" => Regexp::MULTILINE,
43
- }
44
- if args.length < 3 or args.length > 5
45
- raise Puppet::ParseError, ("regsub(): wrong number of arguments" +
46
- " (#{args.length}; min 3, max 5)")
38
+ do |args|
39
+ unless args.length.between?(3, 5)
40
+ raise(Puppet::ParseError,
41
+ "regsubst(): got #{args.length} arguments, expected 3 to 5")
47
42
  end
48
- str, regexp, replacement, flags, lang = args
43
+ target, regexp, replacement, flags, lang = args
49
44
  reflags = 0
50
- global = false
51
- (flags or "").each_byte do |f|
52
- f = f.chr
53
- if f == "G"
54
- global = true
55
- else
56
- fvalue = flag_mapping[f]
57
- if !fvalue
58
- raise Puppet::ParseError, "regsub(): bad flag `#{f}'"
59
- end
60
- reflags |= fvalue
45
+ operation = :sub
46
+ if flags == nil
47
+ flags = []
48
+ elsif flags.respond_to?(:split)
49
+ flags = flags.split('')
50
+ else
51
+ raise(Puppet::ParseError,
52
+ "regsubst(): bad flags parameter #{flags.class}:`#{flags}'")
53
+ end
54
+ flags.each do |f|
55
+ case f
56
+ when 'G' then operation = :gsub
57
+ when 'E' then reflags |= Regexp::EXTENDED
58
+ when 'I' then reflags |= Regexp::IGNORECASE
59
+ when 'M' then reflags |= Regexp::MULTILINE
60
+ else raise(Puppet::ParseError, "regsubst(): bad flag `#{f}'")
61
61
  end
62
62
  end
63
- re = Regexp.compile(regexp, reflags, lang)
64
- if global
65
- result = str.gsub(re, replacement)
63
+ begin
64
+ re = Regexp.compile(regexp, reflags, lang)
65
+ rescue RegexpError, TypeError
66
+ raise(Puppet::ParseError,
67
+ "regsubst(): Bad regular expression `#{regexp}'")
68
+ end
69
+ if target.respond_to?(operation)
70
+ # String parameter -> string result
71
+ result = target.send(operation, re, replacement)
72
+ elsif target.respond_to?(:collect) and
73
+ target.respond_to?(:all?) and
74
+ target.all? { |e| e.respond_to?(operation) }
75
+ # Array parameter -> array result
76
+ result = target.collect { |e|
77
+ e.send(operation, re, replacement)
78
+ }
66
79
  else
67
- result = str.sub(re, replacement)
80
+ raise(Puppet::ParseError,
81
+ "regsubst(): bad target #{target.class}:`#{target}'")
68
82
  end
69
83
  return result
70
84
  end
@@ -23,12 +23,27 @@ class depends on the required class.
23
23
  file { '/foo': notify => Service[foo] }
24
24
  }
25
25
 
26
+ Note that this function only works with clients 0.25 and later, and it will
27
+ fail if used with earlier clients.
28
+
26
29
  ") do |vals|
27
- send(:function_include, vals)
30
+ # Verify that the 'include' function is loaded
31
+ method = Puppet::Parser::Functions.function(:include)
32
+
33
+ send(method, vals)
34
+ if resource.metaparam_compatibility_mode?
35
+ warning "The 'require' function is only compatible with clients at 0.25 and above; including class but not adding dependency"
36
+ else
28
37
  vals = [vals] unless vals.is_a?(Array)
29
38
 
30
- # add a relation from ourselves to each required klass
31
39
  vals.each do |klass|
32
- compiler.catalog.add_edge(resource, findresource(:class, klass))
40
+ # This is a bit hackish, in some ways, but it's the only way
41
+ # to configure a dependency that will make it to the client.
42
+ # The 'obvious' way is just to add an edge in the catalog,
43
+ # but that is considered a containment edge, not a dependency
44
+ # edge, so it usually gets lost on the client.
45
+ ref = Puppet::Parser::Resource::Reference.new(:type => :class, :title => klass)
46
+ resource.set_parameter(:require, ref)
33
47
  end
48
+ end
34
49
  end
@@ -18,7 +18,7 @@ This functions returns a number::
18
18
  Example::
19
19
 
20
20
  if versioncmp('2.6-1', '2.4.5') > 0 {
21
- notify('2.6-1 is > than 2.4.5')
21
+ notice('2.6-1 is > than 2.4.5')
22
22
  }
23
23
 
24
24
  ") do |args|
@@ -62,7 +62,7 @@ class Puppet::Parser::Interpreter
62
62
  def create_parser(environment)
63
63
  begin
64
64
  parser = Puppet::Parser::Parser.new(:environment => environment)
65
- if code = Puppet.settings.value(:code, environment) and code != ""
65
+ if code = Puppet.settings.uninterpolated_value(:code, environment) and code != ""
66
66
  parser.string = code
67
67
  else
68
68
  file = Puppet.settings.value(:manifest, environment)
@@ -11,7 +11,7 @@ end
11
11
  module Puppet::Parser; end
12
12
 
13
13
  class Puppet::Parser::Lexer
14
- attr_reader :last, :file
14
+ attr_reader :last, :file, :lexing_context
15
15
 
16
16
  attr_accessor :line, :indefine
17
17
 
@@ -41,6 +41,11 @@ class Puppet::Parser::Lexer
41
41
  @name.to_s
42
42
  end
43
43
  end
44
+
45
+ def acceptable?(context={})
46
+ # By default tokens are aceeptable in any context
47
+ true
48
+ end
44
49
  end
45
50
 
46
51
  # Maintain a list of tokens.
@@ -171,7 +176,7 @@ class Puppet::Parser::Lexer
171
176
  [self,value]
172
177
  end
173
178
 
174
- TOKENS.add_token :REGEX, %r{/[^/]*/} do |lexer, value|
179
+ regex_token = TOKENS.add_token :REGEX, %r{/[^/\n]*/} do |lexer, value|
175
180
  # Make sure we haven't matched an escaped /
176
181
  while value[-2..-2] == '\\'
177
182
  other = lexer.scan_until(%r{/})
@@ -181,6 +186,10 @@ class Puppet::Parser::Lexer
181
186
  [self, Regexp.new(regex)]
182
187
  end
183
188
 
189
+ def regex_token.acceptable?(context={})
190
+ [:NODE,:LBRACE,:RBRACE,:MATCH,:NOMATCH,:COMMA].include? context[:after]
191
+ end
192
+
184
193
  TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
185
194
 
186
195
  TOKENS.add_token :SQUOTE, "'" do |lexer, value|
@@ -286,36 +295,28 @@ class Puppet::Parser::Lexer
286
295
  # Find the next token that matches a regex. We look for these first.
287
296
  def find_regex_token
288
297
  @regex += 1
289
- matched_token = nil
290
- value = ""
291
- length = 0
298
+ best_token = nil
299
+ best_length = 0
292
300
 
293
301
  # I tried optimizing based on the first char, but it had
294
302
  # a slightly negative affect and was a good bit more complicated.
295
303
  TOKENS.regex_tokens.each do |token|
296
- next unless match_length = @scanner.match?(token.regex)
297
-
298
- # We've found a longer match
299
- if match_length > length
300
- value = @scanner.scan(token.regex)
301
- length = value.length
302
- matched_token = token
304
+ if length = @scanner.match?(token.regex) and token.acceptable?(lexing_context)
305
+ # We've found a longer match
306
+ if length > best_length
307
+ best_length = length
308
+ best_token = token
309
+ end
303
310
  end
304
311
  end
305
312
 
306
- return matched_token, value
313
+ return best_token, @scanner.scan(best_token.regex) if best_token
307
314
  end
308
315
 
309
316
  # Find the next token, returning the string and the token.
310
317
  def find_token
311
318
  @find += 1
312
- matched_token, value = find_regex_token
313
-
314
- unless matched_token
315
- matched_token, value = find_string_token
316
- end
317
-
318
- return matched_token, value
319
+ find_regex_token || find_string_token
319
320
  end
320
321
 
321
322
  def indefine?
@@ -345,6 +346,7 @@ class Puppet::Parser::Lexer
345
346
  @indefine = false
346
347
  @expected = []
347
348
  @commentstack = [ ['', @line] ]
349
+ @lexing_context = {:after => nil, :start_of_line => true}
348
350
  end
349
351
 
350
352
  # Make any necessary changes to the token and/or value.
@@ -417,17 +419,11 @@ class Puppet::Parser::Lexer
417
419
  raise "Could not match '%s'" % nword
418
420
  end
419
421
 
420
- if matched_token.name == :RETURN
421
- # this matches a blank line
422
- if @last_return
423
- # eat the previously accumulated comments
424
- getcomment
425
- end
426
- # since :RETURN skips, we won't survive to munge_token
427
- @last_return = true
428
- else
429
- @last_return = false
430
- end
422
+ newline = matched_token.name == :RETURN
423
+
424
+ # this matches a blank line; eat the previously accumulated comments
425
+ getcomment if lexing_context[:start_of_line] and newline
426
+ lexing_context[:start_of_line] = newline
431
427
 
432
428
  final_token, token_value = munge_token(matched_token, value)
433
429
 
@@ -436,6 +432,8 @@ class Puppet::Parser::Lexer
436
432
  next
437
433
  end
438
434
 
435
+ lexing_context[:after] = final_token.name unless newline
436
+
439
437
  value = token_value[:value]
440
438
 
441
439
  if match = @@pairs[value] and final_token.name != :DQUOTE and final_token.name != :SQUOTE