chef-sugar-sre 5.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative 'constraints'
18
+
19
+ class Chef
20
+ module Sugar
21
+ #
22
+ # The Constraints DSL methods were broken out into this separate
23
+ # file to allow projects (such as Omnibus) to consume the
24
+ # Chef::Sugar::Constraints classes without the DSL methods
25
+ # stepping on existing methods of the same name.
26
+ #
27
+ module Constraints
28
+ extend self
29
+
30
+ #
31
+ # Shortcut method for creating a new {Version} object.
32
+ #
33
+ # @param [String] version
34
+ # the version (as a string) to create
35
+ #
36
+ # @return [Chef::Sugar::Constraints::Version]
37
+ # the new version object
38
+ #
39
+ def version(version)
40
+ Chef::Sugar::Constraints::Version.new(version)
41
+ end
42
+
43
+ #
44
+ # Shortcut method for creating a new {Constraint} object.
45
+ #
46
+ # @param [String, Array<String>] constraints
47
+ # the list of constraints to use
48
+ #
49
+ # @return [Chef::Sugar::Constraints::Constraint]
50
+ # the new constraint object
51
+ #
52
+ def constraint(*constraints)
53
+ Chef::Sugar::Constraints::Constraint.new(*constraints)
54
+ end
55
+ end
56
+
57
+ module DSL
58
+ # @see Chef::Sugar::Constraints#version
59
+ def version(version)
60
+ Chef::Sugar::Constraints::Version.new(version)
61
+ end
62
+
63
+ # @see Chef::Sugar::Constraints#constraint
64
+ def constraint(*constraints)
65
+ Chef::Sugar::Constraints.constraint(*constraints)
66
+ end
67
+
68
+ #
69
+ # This wrapper/convenience method is only available in the recipe DSL. It
70
+ # creates a new version object from the {Chef::VERSION}.
71
+ #
72
+ # @example Check if Chef 11+
73
+ # chef_version.satisfies?('>= 11.0.0')
74
+ #
75
+ # @return [Chef::Sugar::Constraints::Version]
76
+ # a version object, wrapping the current {Chef::VERSION}
77
+ #
78
+ def chef_version
79
+ version(Chef::VERSION)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative '../constraints'
18
+
19
+ class Array
20
+ #
21
+ # Treat an array of objects as version constraints.
22
+ #
23
+ # @see Chef::Sugar::Constraints::Constraint
24
+ #
25
+ # @example Using pure Array<String> objects like constraints
26
+ # ['> 2.0.0', '< 3.0.0'].satisfied_by?('2.1.0')
27
+ #
28
+ # @param [String] version
29
+ # the version to check if it is satisfied
30
+ #
31
+ def satisfied_by?(version)
32
+ Chef::Sugar::Constraints::Constraint.new(*dup).satisfied_by?(version)
33
+ end unless method_defined?(:satisfied_by?)
34
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ class Object
18
+ # An object is blank if it's false, empty, or a whitespace string.
19
+ # This is implemented in rails.
20
+ #
21
+ # @example foo.nil? || foo.empty? can be replaced by foo.blank?
22
+ #
23
+ # @return [true, false]
24
+ def blank?
25
+ respond_to?(:empty?) ? empty? : !self
26
+ end unless method_defined?(:blank?)
27
+ end
@@ -0,0 +1,66 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ # require_relative '../constraints'
18
+
19
+ class String
20
+ #
21
+ # Treat strings as version objects.
22
+ #
23
+ # @see Chef::Sugar::Constraints::Version
24
+ #
25
+ # @example Using pure string objects like versions
26
+ # '1.2.3'.satisfies?('~> 1.2.0')
27
+ #
28
+ # @param [String, Array<String>] constraints
29
+ # the list of constraints to satisfy
30
+ #
31
+ def satisfies?(*constraints)
32
+ Chef::Sugar::Constraints::Version.new(dup).satisfies?(*constraints)
33
+ end unless method_defined?(:satisfies?)
34
+
35
+ #
36
+ # Treat strings as version constraints.
37
+ #
38
+ # @see Chef::Sugar::Constraints::Constraint
39
+ #
40
+ # @example Using pure string objects like constraints
41
+ # '~> 1.2.0'.satisfied_by?('1.2.3')
42
+ #
43
+ # @param [String] version
44
+ # the version to check if it is satisfied
45
+ #
46
+ def satisfied_by?(version)
47
+ Chef::Sugar::Constraints::Constraint.new(dup).satisfied_by?(version)
48
+ end unless method_defined?(:satisfied_by?)
49
+
50
+ #
51
+ # Left-flush a string based off of the number of whitespace characters on the
52
+ # first line. This is especially useful for heredocs when whitespace matters.
53
+ #
54
+ # @example Remove leading whitespace and flush
55
+ # <<-EOH.flush
56
+ # def method
57
+ # 'This is a string!'
58
+ # end
59
+ # EOH #=>"def method\n 'This is a string!'\nend"
60
+ #
61
+ # @return [String]
62
+ #
63
+ def flush
64
+ gsub(/^#{self[/\A\s*/]}/, '').chomp
65
+ end unless method_defined?(:flush)
66
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative 'core_extensions/array'
18
+ require_relative 'core_extensions/string'
19
+ require_relative 'core_extensions/object'
@@ -0,0 +1,146 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ class Chef
18
+ module Sugar
19
+ module DataBag
20
+ class EncryptedDataBagSecretNotGiven < StandardError
21
+ def initialize
22
+ super <<-EOH
23
+ You did not set your `encrypted_data_bag_secret'! In order to use the
24
+ `encrypted_data_bag_item' helper, you must load your encrypted data bag secret
25
+ into the `Chef::Config'.
26
+
27
+ Alternatively, you can pass the secret key as the last parameter to the method
28
+ call. For more information, please see
29
+ http://docs.opscode.com/chef/essentials_data_bags.html#access-from-recipe.
30
+ EOH
31
+ end
32
+ end
33
+
34
+ extend self
35
+
36
+ #
37
+ # Helper method for loading an encrypted data bag item in a similar
38
+ # syntax/recipe DSL method.
39
+ #
40
+ # @param [String] bag
41
+ # the name of the encrypted data bag
42
+ # @param [String] id
43
+ # the id of the encrypted data bag
44
+ # @param [String] secret
45
+ # the encrypted data bag secret raw value
46
+ #
47
+ # @return [Hash]
48
+ #
49
+ def encrypted_data_bag_item(bag, id, secret = nil)
50
+ Chef::Log.debug "Loading encrypted data bag item #{bag}/#{id}"
51
+
52
+ if secret.nil? && Chef::Config[:encrypted_data_bag_secret].nil?
53
+ raise EncryptedDataBagSecretNotGiven.new
54
+ end
55
+
56
+ secret ||= File.read(Chef::Config[:encrypted_data_bag_secret]).strip
57
+ Chef::EncryptedDataBagItem.load(bag, id, secret)
58
+ end
59
+
60
+ #
61
+ # This algorithm attempts to find the data bag entry for the current
62
+ # node's Chef environment. If there are no environment-specific
63
+ # values, the "default" bucket is used. The data bag must follow the
64
+ # schema:
65
+ #
66
+ # {
67
+ # "default": {...},
68
+ # "environment_name": {...},
69
+ # "other_environment": {...},
70
+ # }
71
+ #
72
+ # @param [Node] node
73
+ # the current Chef node
74
+ # @param [String] bag
75
+ # the name of the encrypted data bag
76
+ # @param [String] id
77
+ # the id of the encrypted data bag
78
+ # @param [String] secret
79
+ # the encrypted data bag secret (default's to the +Chef::Config+ value)
80
+ #
81
+ # @return [Hash]
82
+ #
83
+ def encrypted_data_bag_item_for_environment(node, bag, id, secret = nil)
84
+ data = encrypted_data_bag_item(bag, id, secret)
85
+
86
+ if data[node.chef_environment]
87
+ Chef::Log.debug "Using #{node.chef_environment} as the key"
88
+ data[node.chef_environment]
89
+ else
90
+ Chef::Log.debug "#{node.chef_environment} key does not exist, using `default`"
91
+ data['default']
92
+ end
93
+ end
94
+
95
+ #
96
+ # This algorithm attempts to find the data bag entry for the current
97
+ # node's Chef environment. If there are no environment-specific
98
+ # values, the "default" bucket is used. The data bag must follow the
99
+ # schema:
100
+ #
101
+ # {
102
+ # "default": {...},
103
+ # "environment_name": {...},
104
+ # "other_environment": {...},
105
+ # }
106
+ #
107
+ # @param [Node] node
108
+ # the current Chef node
109
+ # @param [String] bag
110
+ # the name of the data bag
111
+ # @param [String] id
112
+ # the id of the data bag
113
+ #
114
+ # @return [Hash]
115
+ #
116
+ def data_bag_item_for_environment(node, bag, id)
117
+ data = Chef::DataBagItem.load(bag, id)
118
+
119
+ if data[node.chef_environment]
120
+ Chef::Log.debug "Using #{node.chef_environment} as the key"
121
+ data[node.chef_environment]
122
+ else
123
+ Chef::Log.debug "#{node.chef_environment} key does not exist, using `default`"
124
+ data['default']
125
+ end
126
+ end
127
+ end
128
+
129
+ module DSL
130
+ # @see Chef::Sugar::DataBag#encrypted_data_bag_item
131
+ def encrypted_data_bag_item(bag, id, secret = nil)
132
+ Chef::Sugar::DataBag.encrypted_data_bag_item(bag, id, secret)
133
+ end
134
+
135
+ # @see Chef::Sugar::DataBag#encrypted_data_bag_item_for_environment
136
+ def encrypted_data_bag_item_for_environment(bag, id, secret = nil)
137
+ Chef::Sugar::DataBag.encrypted_data_bag_item_for_environment(node, bag, id, secret)
138
+ end
139
+
140
+ # @see Chef::Sugar::DataBag#data_bag_item_for_environment
141
+ def data_bag_item_for_environment(bag, id)
142
+ Chef::Sugar::DataBag.data_bag_item_for_environment(node, bag, id)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
15
+ if defined?(Chef::Deprecated::Base)
16
+ class Chef
17
+ class Deprecated
18
+ class ChefSugar < Base
19
+ def id
20
+ 28
21
+ end
22
+ def target
23
+ "chef_sugar.html"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class Chef
31
+ module Sugar
32
+ module Deprecation
33
+ if defined?(Chef::Deprecated::Base)
34
+ def deprecated(message)
35
+ Chef.deprecated(:chef_sugar, message)
36
+ end
37
+ else
38
+ def deprecated(message)
39
+ Chef::Log.warn(message)
40
+ end
41
+ end
42
+ extend self
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ class Chef
18
+ module Sugar
19
+ module Docker
20
+ extend self
21
+
22
+ # these helpers have been moved to core chef
23
+ if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
24
+ #
25
+ # Returns true if the current node is a docker container.
26
+ #
27
+ # @param [Chef::Node] node
28
+ # the node to check
29
+ #
30
+ # @return [Boolean]
31
+ #
32
+ def docker?(node)
33
+ File.exist?('/.dockerinit') || File.exist?('/.dockerenv')
34
+ end
35
+ end
36
+ end
37
+
38
+ module DSL
39
+ if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
40
+ # @see Chef::Sugar::Docker#docker?
41
+ def docker?; Chef::Sugar::Docker.docker?(node); end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,227 @@
1
+ class Chef
2
+ module Sugar
3
+ module Filters
4
+ #
5
+ # Evaluate resources at compile time instead of converge time.
6
+ #
7
+ class AtCompileTime
8
+ def initialize(recipe)
9
+ @recipe = recipe
10
+ end
11
+
12
+ def evaluate(&block)
13
+ instance_eval(&block)
14
+ end
15
+
16
+ def method_missing(m, *args, &block)
17
+ resource = @recipe.send(m, *args, &block)
18
+
19
+ if resource.is_a?(Chef::Resource)
20
+ actions = Array(resource.action)
21
+ resource.action(:nothing)
22
+
23
+ actions.each do |action|
24
+ resource.run_action(action)
25
+ end
26
+ end
27
+
28
+ resource
29
+ end
30
+ end
31
+
32
+ #
33
+ # A top-level class for manipulation the resource collection.
34
+ #
35
+ class Injector
36
+ def initialize(recipe, identifier, placement)
37
+ @recipe = recipe
38
+ @resource_collection = @recipe.run_context.resource_collection
39
+ @resource = @resource_collection.lookup(identifier)
40
+ @placement = placement
41
+ end
42
+
43
+ def evaluate(&block)
44
+ instance_eval(&block)
45
+ end
46
+
47
+ def insert_before(resource, new_resource)
48
+ @resource_collection.instance_eval do
49
+ # Remove the resource because it's automatically created
50
+ @resources.delete_at(@resources_by_name[new_resource.to_s])
51
+ @resources_by_name.delete(new_resource.to_s)
52
+
53
+ index = @resources_by_name[resource.to_s]
54
+ @resources.insert(index, new_resource)
55
+ @resources_by_name[new_resource.to_s] = index
56
+ end
57
+ end
58
+
59
+ def insert_after(resource, new_resource)
60
+ @resource_collection.instance_eval do
61
+ # Remove the resource because it's automatically created
62
+ @resources.delete_at(@resources_by_name[new_resource.to_s])
63
+ @resources_by_name.delete(new_resource.to_s)
64
+
65
+ index = @resources_by_name[resource.to_s] + 2
66
+ @resources.insert(index, new_resource)
67
+ @resources_by_name[new_resource.to_s] = index
68
+ end
69
+ end
70
+
71
+ def method_missing(m, *args, &block)
72
+ new_resource = @recipe.send(m, *args, &block)
73
+
74
+ case @placement
75
+ when :before
76
+ insert_before(@resource, new_resource)
77
+ when :after
78
+ insert_after(@resource, new_resource)
79
+ else
80
+ super
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ module DSL
87
+ #
88
+ # Dynamically run resources specified in the block during the compilation
89
+ # phase, instead of the convergence phase.
90
+ #
91
+ # @example The old way
92
+ # package('apache2') do
93
+ # action :nothing
94
+ # end.run_action(:install)
95
+ #
96
+ # @example The new way
97
+ # at_compile_time do
98
+ # package('apache2')
99
+ # end
100
+ #
101
+ # @example Resource actions are run in order
102
+ # at_compile_time do
103
+ # service 'apache2' do
104
+ # action [:enable, :start] # run_action(:enable), run_action(:start)
105
+ # end
106
+ # end
107
+ #
108
+ def at_compile_time(&block)
109
+ Chef::Sugar::Filters::AtCompileTime.new(self).evaluate(&block)
110
+ end
111
+
112
+ #
113
+ # Dynamically insert resources before an existing resource in the
114
+ # resource_collection.
115
+ #
116
+ # @example Write a custom template before the apache2 service actions
117
+ # are run
118
+ # before 'service[apache2]' do
119
+ # template '/etc/apache2/thing.conf' do
120
+ # source '...'
121
+ # end
122
+ # end
123
+ #
124
+ #
125
+ # @param [String] identifier
126
+ # the +resource[name]+ identifier string
127
+ #
128
+ def before(identifier, &block)
129
+ Chef::Sugar::Filters::Injector.new(self, identifier, :before).evaluate(&block)
130
+ end
131
+
132
+ #
133
+ # Dynamically insert resources after an existing resource in the
134
+ # resource_collection.
135
+ #
136
+ # @example Write a custom template after the apache2 service actions
137
+ # are run
138
+ # after 'service[apache2]' do
139
+ # template '/etc/apache2/thing.conf' do
140
+ # source '...'
141
+ # end
142
+ # end
143
+ #
144
+ #
145
+ # @param [String] identifier
146
+ # the +resource[name]+ identifier string
147
+ #
148
+ def after(identifier, &block)
149
+ Chef::Sugar::Filters::Injector.new(self, identifier, :after).evaluate(&block)
150
+ end
151
+ end
152
+
153
+ module RecipeDSL
154
+ #
155
+ # @deprecated The description is in the method body pretty accurately...
156
+ #
157
+ def compile_time(&block)
158
+ message = <<-EOH
159
+
160
+ The Chef Sugar recipe DSL method `compile_time' has been renamed to
161
+ `at_compile_time'! This is a breaking change that was released in a patch
162
+ version, so please continue reading to understand the necessary semantic
163
+ versioning violation.
164
+
165
+ Chef Software implemented a version of `compile_time' in Chef 12.1, breaking any
166
+ cookbook that uses or depends on Chef Sugar on Chef 12.1:
167
+
168
+ https://www.chef.io/blog/2015/03/03/chef-12-1-0-released
169
+
170
+ In order to progress Chef Sugar forward, the DSL method has been renamed to
171
+ avoid the namespace collision.
172
+
173
+ In short, you should change this:
174
+
175
+ compile_time do
176
+ # ...
177
+ end
178
+
179
+ to this:
180
+
181
+ at_compile_time do
182
+ # ...
183
+ end
184
+
185
+ EOH
186
+
187
+ if Chef::Resource::ChefGem.instance_methods(false).include?(:compile_time)
188
+ message << <<-EOH
189
+ You are running a version of Chef Client that includes the `compile_time'
190
+ attribute on core Chef resources (most likely Chef 12.1+). Instead of continuing
191
+ and having Chef provide you with an obscure error message, I am going to error
192
+ here. There is no way for the Chef Recipe to successfully continue unless you
193
+ change the Chef Sugar `compile_time' method to `at_compile_time' in your Chef
194
+ recipes.
195
+
196
+ You should NOT change resource-level `compile_time' attributes:
197
+
198
+ package "foo" do
199
+ compile_time true # Do NOT change these
200
+ end
201
+
202
+ I truly apologize for the inconvienence and hope the reason for introducing this
203
+ breaking change is clear. I am sorry if it causes extra work, but I promise this
204
+ error message is much more informative than "wrong number of arguments".
205
+
206
+ If you have any questions, please feel free to open an issue on GitHub at:
207
+
208
+ https://github.com/sethvargo/chef-sugar
209
+
210
+ Thank you, and have a great day!
211
+ EOH
212
+ raise RuntimeError, message
213
+ else
214
+ message << <<-EOH
215
+ You are running a version of Chef Client that does not include the
216
+ `compile_time' attribute on core Chef resources (most likely less than
217
+ Chef 12.1), so this is just a warning. Please consider changing the Chef Sugar
218
+ `compile_time' method to `at_compile_time' in your Chef recipes. If you upgrade
219
+ Chef, your recipes WILL break.
220
+ EOH
221
+ Chef::Log.warn(message)
222
+ at_compile_time(&block)
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end