poise-profiler 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +60 -16
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/lib/poise_profiler.rb +2 -1
- data/lib/poise_profiler/base.rb +121 -0
- data/lib/poise_profiler/cheftie.rb +4 -20
- data/lib/poise_profiler/config.rb +68 -0
- data/lib/poise_profiler/core_ext.rb +19 -0
- data/lib/poise_profiler/core_ext/cookbook_version.rb +42 -0
- data/lib/poise_profiler/core_ext/dispatcher.rb +45 -0
- data/lib/poise_profiler/core_ext/event_base.rb +41 -0
- data/lib/poise_profiler/core_ext/run_context.rb +53 -0
- data/lib/poise_profiler/{handler.rb → timing.rb} +7 -41
- data/lib/poise_profiler/version.rb +1 -1
- data/test/gemfiles/chef-12.0.gemfile +4 -0
- data/test/gemfiles/chef-12.1.gemfile +4 -0
- data/test/gemfiles/chef-12.10.gemfile +23 -0
- data/test/gemfiles/chef-12.11.gemfile +23 -0
- data/test/gemfiles/chef-12.12.gemfile +22 -0
- data/test/gemfiles/chef-12.13.gemfile +22 -0
- data/test/gemfiles/chef-12.14.gemfile +19 -0
- data/test/gemfiles/chef-12.15.gemfile +19 -0
- data/test/gemfiles/chef-12.16.gemfile +19 -0
- data/test/gemfiles/chef-12.17.gemfile +19 -0
- data/test/gemfiles/chef-12.18.gemfile +19 -0
- data/test/gemfiles/chef-12.19.gemfile +19 -0
- data/test/gemfiles/chef-12.2.gemfile +4 -0
- data/test/gemfiles/chef-12.3.gemfile +4 -0
- data/test/gemfiles/chef-12.4.gemfile +5 -2
- data/test/gemfiles/chef-12.5.gemfile +4 -0
- data/test/gemfiles/chef-12.6.gemfile +4 -0
- data/test/gemfiles/chef-12.7.gemfile +23 -0
- data/test/gemfiles/chef-12.8.gemfile +23 -0
- data/test/gemfiles/chef-12.9.gemfile +23 -0
- data/test/gemfiles/chef-12.gemfile +1 -1
- data/test/gemfiles/chef-13.0.gemfile +19 -0
- data/test/gemfiles/chef-13.gemfile +19 -0
- data/test/gemfiles/master.gemfile +1 -0
- data/test/spec/config_spec.rb +61 -0
- data/test/spec/integration_spec.rb +1 -1
- data/test/spec/{default_spec.rb → timing_spec.rb} +44 -10
- metadata +45 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e984488349e52e2006619ea29e69fc5392eecacc
|
4
|
+
data.tar.gz: f5ce15b89376f591c8c1f193b14240349572d956
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b1d594912bd19a629f1fe57f24ef874273c15efd6940d98fe437f180f04c69d77fe894a86e167207724f337b646d2362fc5ef9af59ee5f7fff608183d264e94
|
7
|
+
data.tar.gz: 0a621221e1d9aa4c8ab957265a2a303e2a694618ffae8d7f71f7a1e243dc5fa79c00079c86698728977052234d7cd37c199ef9225a274bd656d697f6d0f50b4c
|
data/.travis.yml
CHANGED
@@ -1,22 +1,66 @@
|
|
1
1
|
sudo: false
|
2
2
|
cache: bundler
|
3
3
|
language: ruby
|
4
|
-
rvm:
|
5
|
-
- '2.2'
|
6
4
|
env:
|
7
5
|
global:
|
8
|
-
|
9
|
-
before_install:
|
10
|
-
|
6
|
+
- secure: DxJdl4xHPBB3mdM2c0qhdjpxEkWuv0vF9MFrrblSjM3VF5kIkkhSRG+zvyJNg2u+zu76XCEvf+pEt2Ltsl7TzY/AdkeyyhEX2JxcPMkAl5KJmssEQPHkkLowTCK4rfVuakCDjkuXRReSdfH3vBSAX1/SqUZelVZjNV4AZcGHykv5WE0hBmOMGuY9mmsZyg7f91vifCGWk+7SexF+jcuqQh7ZKeJiLcERMdS2K568zkOYZyHXaS+31ic5HW3Jfh929+chg0iSCXL7xhCoUFF4K/aUfi/40LVVHAnBVi0NT/79/KbQBKvYYsCPr0Bw4QqVfRuz6Puxf0FWpLmuRdj1gxvHRKJ18PoKXdET+XsORJV+Qs0EXATR+bzqT9hXSJ16DEaJn8Sx4bA9YqDlBSSGwHqlLj3ql78e5UqkG4yHSLPTjz1uDA+56ZadTLliWR6uFna4HSPx8T4z7FSYMqoLS2Z59I3/JhZ/aSlEnW4FVpQW5XXxz1KVFnOHoz9gGHq+uJChFaAM2mq1MlXzbflpnLe3D/2k2daC0ss4dRrE2jplqpDWwjSK4CrXNRjKiiDr/KScgFYPz7wNg1Acq2hbYXx5J/pTi+sSjZjEUtXRTVzutm9KgLNPlz/MmUamd1maK9APhFdlrOTGFF4fXgE5OeVcSz+lF+Zi8qiXxfUFuvQ=
|
7
|
+
before_install:
|
8
|
+
- 'if [[ $BUNDLE_GEMFILE == *master.gemfile ]]; then gem update --system; fi'
|
9
|
+
- gem --version
|
10
|
+
- gem install bundler
|
11
|
+
- bundle --version
|
12
|
+
- 'bundle config --local path ${BUNDLE_PATH:-$(dirname $BUNDLE_GEMFILE)/vendor/bundle}'
|
13
|
+
- bundle config --local bin $PWD/bin
|
14
|
+
install: bundle update --jobs=3 --retry=3
|
11
15
|
script:
|
12
|
-
-
|
13
|
-
|
14
|
-
|
15
|
-
-
|
16
|
-
|
17
|
-
-
|
18
|
-
|
19
|
-
-
|
20
|
-
|
21
|
-
-
|
22
|
-
|
16
|
+
- ./bin/rake travis
|
17
|
+
matrix:
|
18
|
+
include:
|
19
|
+
- rvm: 2.3.1
|
20
|
+
gemfile: test/gemfiles/chef-12.gemfile
|
21
|
+
- rvm: 2.4.1
|
22
|
+
gemfile: test/gemfiles/chef-13.gemfile
|
23
|
+
- rvm: 2.1.4
|
24
|
+
gemfile: test/gemfiles/chef-12.0.gemfile
|
25
|
+
- rvm: 2.1.4
|
26
|
+
gemfile: test/gemfiles/chef-12.1.gemfile
|
27
|
+
- rvm: 2.1.4
|
28
|
+
gemfile: test/gemfiles/chef-12.2.gemfile
|
29
|
+
- rvm: 2.1.4
|
30
|
+
gemfile: test/gemfiles/chef-12.3.gemfile
|
31
|
+
- rvm: 2.1.6
|
32
|
+
gemfile: test/gemfiles/chef-12.4.gemfile
|
33
|
+
- rvm: 2.1.6
|
34
|
+
gemfile: test/gemfiles/chef-12.5.gemfile
|
35
|
+
- rvm: 2.1.6
|
36
|
+
gemfile: test/gemfiles/chef-12.6.gemfile
|
37
|
+
- rvm: 2.1.6
|
38
|
+
gemfile: test/gemfiles/chef-12.7.gemfile
|
39
|
+
- rvm: 2.1.6
|
40
|
+
gemfile: test/gemfiles/chef-12.8.gemfile
|
41
|
+
- rvm: 2.1.8
|
42
|
+
gemfile: test/gemfiles/chef-12.9.gemfile
|
43
|
+
- rvm: 2.1.8
|
44
|
+
gemfile: test/gemfiles/chef-12.10.gemfile
|
45
|
+
- rvm: 2.1.8
|
46
|
+
gemfile: test/gemfiles/chef-12.11.gemfile
|
47
|
+
- rvm: 2.1.8
|
48
|
+
gemfile: test/gemfiles/chef-12.12.gemfile
|
49
|
+
- rvm: 2.1.9
|
50
|
+
gemfile: test/gemfiles/chef-12.13.gemfile
|
51
|
+
- rvm: 2.3.1
|
52
|
+
gemfile: test/gemfiles/chef-12.14.gemfile
|
53
|
+
- rvm: 2.3.1
|
54
|
+
gemfile: test/gemfiles/chef-12.15.gemfile
|
55
|
+
- rvm: 2.3.1
|
56
|
+
gemfile: test/gemfiles/chef-12.16.gemfile
|
57
|
+
- rvm: 2.3.1
|
58
|
+
gemfile: test/gemfiles/chef-12.17.gemfile
|
59
|
+
- rvm: 2.3.1
|
60
|
+
gemfile: test/gemfiles/chef-12.18.gemfile
|
61
|
+
- rvm: 2.3.1
|
62
|
+
gemfile: test/gemfiles/chef-12.19.gemfile
|
63
|
+
- rvm: 2.4.1
|
64
|
+
gemfile: test/gemfiles/chef-13.0.gemfile
|
65
|
+
- rvm: 2.4.1
|
66
|
+
gemfile: test/gemfiles/master.gemfile
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
data/lib/poise_profiler.rb
CHANGED
@@ -0,0 +1,121 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
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 'chef/config'
|
18
|
+
require 'chef/event_dispatch/base'
|
19
|
+
require 'chef/json_compat'
|
20
|
+
require 'chef/version'
|
21
|
+
|
22
|
+
begin
|
23
|
+
require 'chef/chef_class'
|
24
|
+
rescue LoadError
|
25
|
+
# ¯\_(ツ)_/¯ Chef < 12.3.
|
26
|
+
end
|
27
|
+
|
28
|
+
module PoiseProfiler
|
29
|
+
# Base class for poise-provider event handlers.
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
# @since 1.1.0
|
33
|
+
class Base < Chef::EventDispatch::Base
|
34
|
+
include Singleton
|
35
|
+
|
36
|
+
# Install this event handler in to Chef.
|
37
|
+
#
|
38
|
+
# @return [void]
|
39
|
+
def self.install!
|
40
|
+
# Clear instance state to be safe.
|
41
|
+
instance.reset!
|
42
|
+
# For pre-Chef.run_context, use the monkey patch. Otherwise use the
|
43
|
+
# events API or global config.
|
44
|
+
if Gem::Version.create(Chef::VERSION) <= Gem::Version.create('12.2.1')
|
45
|
+
Chef::Log.debug("Registering poise-profiler handler #{self} using monkey patch")
|
46
|
+
instance._monkey_patch_old_chef!
|
47
|
+
elsif Chef.run_context && Chef.run_context.events
|
48
|
+
# :nocov:
|
49
|
+
Chef::Log.debug("Registering poise-profiler handler #{self} using events API")
|
50
|
+
Chef.run_context.events.register(instance)
|
51
|
+
# :nocov:
|
52
|
+
else
|
53
|
+
Chef::Log.debug("Registering poise-profiler handler #{self} using global config")
|
54
|
+
Chef::Config[:event_handlers] |= [instance]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Used in {#_monkey_patch_old_chef}.
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
attr_writer :events, :monkey_patched
|
62
|
+
|
63
|
+
# Hook to reset the handler for testing.
|
64
|
+
#
|
65
|
+
# @api private
|
66
|
+
# @return [void]
|
67
|
+
def reset!
|
68
|
+
@events = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# Inject this instance for Chef < 12.3. Don't call this on newer Chef.
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
# @see Base.install
|
75
|
+
# @return [void]
|
76
|
+
def _monkey_patch_old_chef!
|
77
|
+
require 'chef/event_dispatch/dispatcher'
|
78
|
+
instance = self
|
79
|
+
orig_method = Chef::EventDispatch::Dispatcher.instance_method(:library_file_loaded)
|
80
|
+
Chef::EventDispatch::Dispatcher.send(:define_method, :library_file_loaded) do |filename|
|
81
|
+
instance.events = self
|
82
|
+
instance.monkey_patched = false
|
83
|
+
@subscribers |= [instance]
|
84
|
+
Chef::EventDispatch::Dispatcher.send(:define_method, :library_file_loaded, orig_method)
|
85
|
+
orig_method.bind(self).call(filename)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Convenience helper to print a line of text out via the event handler.
|
92
|
+
#
|
93
|
+
# @api private
|
94
|
+
# @param line [String] Line to display.
|
95
|
+
# @return [void]
|
96
|
+
def puts(line)
|
97
|
+
events.stream_output(:profiler, line+"\n")
|
98
|
+
end
|
99
|
+
|
100
|
+
# Accessor for the current global event handler. The is either set via
|
101
|
+
# {#_monkey_patch_old_chef} (<= 12.2.1) or retrieved via the global API (>=
|
102
|
+
# 12.3).
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
# return [Chef::EventDispatch::Dispatcher]
|
106
|
+
def events
|
107
|
+
@events ||= Chef.run_context.events
|
108
|
+
end
|
109
|
+
|
110
|
+
# Accessor for the profiler config.
|
111
|
+
#
|
112
|
+
# @api private
|
113
|
+
# @return [PoiseProfiler::Config]
|
114
|
+
def config
|
115
|
+
# This could be a single global but it doesn't use enough RAM or CPU
|
116
|
+
# cycles that I care.
|
117
|
+
@config ||= PoiseProfiler::Config.new
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -14,24 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
rescue LoadError
|
20
|
-
# ¯\_(ツ)_/¯ Chef < 12.3.
|
21
|
-
end
|
22
|
-
require 'chef/config'
|
23
|
-
require 'poise_profiler/handler'
|
17
|
+
require 'poise_profiler'
|
18
|
+
require 'poise_profiler/core_ext'
|
24
19
|
|
25
|
-
# Install the
|
26
|
-
|
27
|
-
Chef::Log.debug('Registering poise-profiler using monkey patch')
|
28
|
-
PoiseProfiler::Handler.instance.monkey_patch_old_chef!
|
29
|
-
elsif Chef.run_context && Chef.run_context.events
|
30
|
-
# :nocov:
|
31
|
-
Chef::Log.debug('Registering poise-profiler using events api')
|
32
|
-
Chef.run_context.events.register(PoiseProfiler::Handler.instance)
|
33
|
-
# :nocov:
|
34
|
-
else
|
35
|
-
Chef::Log.debug('Registering poise-profiler using global config')
|
36
|
-
Chef::Config[:event_handlers] << PoiseProfiler::Handler.instance
|
37
|
-
end
|
20
|
+
# Install the handlers.
|
21
|
+
PoiseProfiler::Timing.install!
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
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 'yaml'
|
18
|
+
|
19
|
+
require 'chef/mash'
|
20
|
+
begin
|
21
|
+
require 'chef/chef_class'
|
22
|
+
rescue LoadError
|
23
|
+
# ¯\_(ツ)_/¯ Chef < 12.3.
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
module PoiseProfiler
|
28
|
+
# Configuration wrapper for poise-profiler to combine input from a number of
|
29
|
+
# sources.
|
30
|
+
#
|
31
|
+
# @since 1.1.0
|
32
|
+
# @api private
|
33
|
+
# @example
|
34
|
+
# cfg = Config.new
|
35
|
+
# puts cfg[:profile_memory]
|
36
|
+
class Config < Mash
|
37
|
+
def initialize
|
38
|
+
super
|
39
|
+
gather_from_env
|
40
|
+
gather_from_node
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Find configuration data in environment variables. This is the only option
|
46
|
+
# on Chef 12.0, 12.1, and 12.2.
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def gather_from_env
|
50
|
+
ENV.each do |key, value|
|
51
|
+
if key.downcase =~ /^poise(_|-)profiler_(.+)$/
|
52
|
+
self[$2] = YAML.safe_load(value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Find configuration data in node attributes.
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
def gather_from_node
|
61
|
+
return unless defined?(Chef.node)
|
62
|
+
(Chef.node['poise-profiler'] || {}).each do |key, value|
|
63
|
+
self[key] = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
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 'poise_profiler/core_ext/cookbook_version'
|
18
|
+
require 'poise_profiler/core_ext/dispatcher'
|
19
|
+
require 'poise_profiler/core_ext/event_base'
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
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 'chef/cookbook_version'
|
18
|
+
require 'chef/version'
|
19
|
+
|
20
|
+
|
21
|
+
module PoiseProfiler
|
22
|
+
module CoreExt
|
23
|
+
# Monkeypatch extensions for Chef::CookbookVersion to support the
|
24
|
+
# new recipe_loaded event.
|
25
|
+
#
|
26
|
+
# @since 1.1.0
|
27
|
+
# @api private
|
28
|
+
module CookbookVersion
|
29
|
+
def load_recipe(recipe_name, run_context)
|
30
|
+
super.tap do |recipe|
|
31
|
+
run_context.events.recipe_loaded("#{name}::#{recipe_name}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Monkeypatch us in for ?. TODO THIS
|
36
|
+
if Gem::Version.create(Chef::VERSION) < Gem::Version.create('14')
|
37
|
+
Chef::CookbookVersion.prepend(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
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 'chef/event_dispatch/dispatcher'
|
18
|
+
require 'chef/version'
|
19
|
+
|
20
|
+
|
21
|
+
module PoiseProfiler
|
22
|
+
module CoreExt
|
23
|
+
# Monkeypatch extensions for Chef::EventDispatch::Dispatcher to support the
|
24
|
+
# new recipe_loaded event.
|
25
|
+
#
|
26
|
+
# @since 1.1.0
|
27
|
+
# @api private
|
28
|
+
module Dispatcher
|
29
|
+
def recipe_loaded(*args)
|
30
|
+
if defined?(call_subscribers)
|
31
|
+
call_subscribers(:recipe_loaded, *args)
|
32
|
+
else
|
33
|
+
@subscribers.each { |s| s.recipe_loaded(*args) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Monkeypatch us in for ?. TODO THIS
|
38
|
+
if Gem::Version.create(Chef::VERSION) < Gem::Version.create('14')
|
39
|
+
Chef::EventDispatch::Dispatcher.include(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|