garcun 0.0.2

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.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +17 -0
  3. data/.gitignore +197 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +521 -0
  8. data/Rakefile +47 -0
  9. data/garcun.gemspec +83 -0
  10. data/lib/garcon.rb +290 -0
  11. data/lib/garcon/chef/chef_helpers.rb +343 -0
  12. data/lib/garcon/chef/coerce/coercer.rb +134 -0
  13. data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
  14. data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
  15. data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
  16. data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
  17. data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
  18. data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
  19. data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
  20. data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
  21. data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
  22. data/lib/garcon/chef/handler/devreporter.rb +127 -0
  23. data/lib/garcon/chef/log.rb +64 -0
  24. data/lib/garcon/chef/node.rb +100 -0
  25. data/lib/garcon/chef/provider/civilize.rb +209 -0
  26. data/lib/garcon/chef/provider/development.rb +159 -0
  27. data/lib/garcon/chef/provider/download.rb +420 -0
  28. data/lib/garcon/chef/provider/house_keeping.rb +265 -0
  29. data/lib/garcon/chef/provider/node_cache.rb +31 -0
  30. data/lib/garcon/chef/provider/partial.rb +183 -0
  31. data/lib/garcon/chef/provider/recovery.rb +80 -0
  32. data/lib/garcon/chef/provider/zip_file.rb +271 -0
  33. data/lib/garcon/chef/resource/attribute.rb +52 -0
  34. data/lib/garcon/chef/resource/base_dsl.rb +174 -0
  35. data/lib/garcon/chef/resource/blender.rb +140 -0
  36. data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
  37. data/lib/garcon/chef/resource/resource_name.rb +109 -0
  38. data/lib/garcon/chef/secret_bag.rb +204 -0
  39. data/lib/garcon/chef/validations.rb +76 -0
  40. data/lib/garcon/chef_inclusions.rb +151 -0
  41. data/lib/garcon/configuration.rb +138 -0
  42. data/lib/garcon/core_ext.rb +39 -0
  43. data/lib/garcon/core_ext/array.rb +27 -0
  44. data/lib/garcon/core_ext/binding.rb +64 -0
  45. data/lib/garcon/core_ext/boolean.rb +66 -0
  46. data/lib/garcon/core_ext/duration.rb +271 -0
  47. data/lib/garcon/core_ext/enumerable.rb +34 -0
  48. data/lib/garcon/core_ext/file.rb +127 -0
  49. data/lib/garcon/core_ext/filetest.rb +62 -0
  50. data/lib/garcon/core_ext/hash.rb +279 -0
  51. data/lib/garcon/core_ext/kernel.rb +159 -0
  52. data/lib/garcon/core_ext/lazy.rb +222 -0
  53. data/lib/garcon/core_ext/method_access.rb +243 -0
  54. data/lib/garcon/core_ext/module.rb +92 -0
  55. data/lib/garcon/core_ext/nil.rb +53 -0
  56. data/lib/garcon/core_ext/numeric.rb +44 -0
  57. data/lib/garcon/core_ext/object.rb +342 -0
  58. data/lib/garcon/core_ext/pathname.rb +152 -0
  59. data/lib/garcon/core_ext/process.rb +41 -0
  60. data/lib/garcon/core_ext/random.rb +497 -0
  61. data/lib/garcon/core_ext/string.rb +312 -0
  62. data/lib/garcon/core_ext/struct.rb +49 -0
  63. data/lib/garcon/core_ext/symbol.rb +170 -0
  64. data/lib/garcon/core_ext/time.rb +234 -0
  65. data/lib/garcon/exceptions.rb +101 -0
  66. data/lib/garcon/inflections.rb +237 -0
  67. data/lib/garcon/inflections/defaults.rb +79 -0
  68. data/lib/garcon/inflections/inflections.rb +182 -0
  69. data/lib/garcon/inflections/rules_collection.rb +37 -0
  70. data/lib/garcon/secret.rb +271 -0
  71. data/lib/garcon/stash/format.rb +114 -0
  72. data/lib/garcon/stash/journal.rb +226 -0
  73. data/lib/garcon/stash/queue.rb +83 -0
  74. data/lib/garcon/stash/serializer.rb +86 -0
  75. data/lib/garcon/stash/store.rb +435 -0
  76. data/lib/garcon/task.rb +31 -0
  77. data/lib/garcon/task/atomic.rb +151 -0
  78. data/lib/garcon/task/atomic_boolean.rb +127 -0
  79. data/lib/garcon/task/condition.rb +99 -0
  80. data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
  81. data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
  82. data/lib/garcon/task/count_down_latch.rb +92 -0
  83. data/lib/garcon/task/delay.rb +196 -0
  84. data/lib/garcon/task/dereferenceable.rb +144 -0
  85. data/lib/garcon/task/event.rb +119 -0
  86. data/lib/garcon/task/executor.rb +275 -0
  87. data/lib/garcon/task/executor_options.rb +59 -0
  88. data/lib/garcon/task/future.rb +107 -0
  89. data/lib/garcon/task/immediate_executor.rb +84 -0
  90. data/lib/garcon/task/ivar.rb +171 -0
  91. data/lib/garcon/task/lazy_reference.rb +74 -0
  92. data/lib/garcon/task/monotonic_time.rb +69 -0
  93. data/lib/garcon/task/obligation.rb +256 -0
  94. data/lib/garcon/task/observable.rb +101 -0
  95. data/lib/garcon/task/priority_queue.rb +234 -0
  96. data/lib/garcon/task/processor_count.rb +128 -0
  97. data/lib/garcon/task/read_write_lock.rb +304 -0
  98. data/lib/garcon/task/safe_task_executor.rb +58 -0
  99. data/lib/garcon/task/single_thread_executor.rb +97 -0
  100. data/lib/garcon/task/thread_pool/cached.rb +71 -0
  101. data/lib/garcon/task/thread_pool/executor.rb +294 -0
  102. data/lib/garcon/task/thread_pool/fixed.rb +61 -0
  103. data/lib/garcon/task/thread_pool/worker.rb +90 -0
  104. data/lib/garcon/task/timer.rb +44 -0
  105. data/lib/garcon/task/timer_set.rb +194 -0
  106. data/lib/garcon/task/timer_task.rb +377 -0
  107. data/lib/garcon/task/waitable_list.rb +58 -0
  108. data/lib/garcon/utility/ansi.rb +199 -0
  109. data/lib/garcon/utility/at_random.rb +77 -0
  110. data/lib/garcon/utility/crypto.rb +292 -0
  111. data/lib/garcon/utility/equalizer.rb +146 -0
  112. data/lib/garcon/utility/faker/extensions/array.rb +22 -0
  113. data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
  114. data/lib/garcon/utility/faker/faker.rb +164 -0
  115. data/lib/garcon/utility/faker/faker/company.rb +17 -0
  116. data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
  117. data/lib/garcon/utility/faker/faker/version.rb +3 -0
  118. data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
  119. data/lib/garcon/utility/faker/locales/en.yml +21 -0
  120. data/lib/garcon/utility/file_helper.rb +170 -0
  121. data/lib/garcon/utility/hookers.rb +178 -0
  122. data/lib/garcon/utility/interpolation.rb +90 -0
  123. data/lib/garcon/utility/memstash.rb +364 -0
  124. data/lib/garcon/utility/misc.rb +54 -0
  125. data/lib/garcon/utility/msg_from_god.rb +62 -0
  126. data/lib/garcon/utility/retry.rb +238 -0
  127. data/lib/garcon/utility/timeout.rb +58 -0
  128. data/lib/garcon/utility/uber/builder.rb +91 -0
  129. data/lib/garcon/utility/uber/callable.rb +7 -0
  130. data/lib/garcon/utility/uber/delegates.rb +13 -0
  131. data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
  132. data/lib/garcon/utility/uber/options.rb +101 -0
  133. data/lib/garcon/utility/uber/uber_version.rb +3 -0
  134. data/lib/garcon/utility/uber/version.rb +33 -0
  135. data/lib/garcon/utility/url_helper.rb +100 -0
  136. data/lib/garcon/utils.rb +29 -0
  137. data/lib/garcon/version.rb +62 -0
  138. data/lib/garcun.rb +24 -0
  139. metadata +680 -0
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'bundler/gem_tasks'
21
+
22
+ desc 'Generate Ruby documentation'
23
+ task :yard do
24
+ require 'yard'
25
+ YARD::Rake::YardocTask.new do |t|
26
+ t.files = ['**/*.rb', '-', 'README.md', 'LICENSE']
27
+ t.stats_options = %w(--list-undoc)
28
+ end
29
+ end
30
+
31
+ task doc: %w(yard)
32
+
33
+ require "rspec/core/rake_task"
34
+
35
+ RSpec::Core::RakeTask.new(:spec)
36
+ task default: [:spec]
37
+
38
+ begin
39
+ require "rubocop/rake_task"
40
+
41
+ Rake::Task[:default].enhance [:rubocop]
42
+
43
+ RuboCop::RakeTask.new do |task|
44
+ task.options << "--display-cop-names"
45
+ end
46
+ rescue LoadError
47
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ lib = File.expand_path('../lib', __FILE__)
21
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
22
+ require 'garcon/version'
23
+
24
+ Gem::Specification.new do |gem|
25
+ gem.name = 'garcun'
26
+ gem.version = Garcon::VERSION.dup
27
+ gem.authors = [ 'Stefano Harding' ]
28
+ gem.email = [ 'riddopic@gmail.com' ]
29
+ gem.description = 'A useful collection of methods to make cooking more fun'
30
+ gem.summary = gem.description
31
+ gem.homepage = 'https://github.com/riddopic/garcun'
32
+ gem.license = 'Apache 2.0'
33
+
34
+ gem.require_paths = %w[lib]
35
+ gem.files = `git ls-files`.split($/)
36
+ gem.test_files = `git ls-files -- spec`.split($/)
37
+ gem.extra_rdoc_files = %w[LICENSE README.md]
38
+ gem.required_ruby_version = '>= 2.0.0'
39
+
40
+ gem.add_dependency 'chef', '>= 11.0'
41
+ gem.add_dependency 'bundler'
42
+
43
+ # Development gems
44
+ gem.add_development_dependency 'rake', '~> 10.4'
45
+ gem.add_development_dependency 'yard', '~> 0.8'
46
+ gem.add_development_dependency 'pry'
47
+ gem.add_development_dependency 'stove', '~> 3.2', '>= 3.2.3'
48
+ gem.add_development_dependency 'thor'
49
+
50
+ # Test gems
51
+ gem.add_development_dependency 'rspec', '~> 3.2'
52
+ gem.add_development_dependency 'rspec-its', '~> 1.2'
53
+ gem.add_development_dependency 'chefspec', '~> 4.2'
54
+ gem.add_development_dependency 'fuubar', '~> 2.0'
55
+ gem.add_development_dependency 'simplecov', '~> 0.9'
56
+ gem.add_development_dependency 'foodcritic', '~> 4.0'
57
+ gem.add_development_dependency 'berkshelf', '~> 3.2'
58
+ gem.add_development_dependency 'serverspec'
59
+ gem.add_development_dependency 'inch'
60
+ gem.add_development_dependency 'yardstick'
61
+ gem.add_development_dependency 'guard'
62
+ gem.add_development_dependency 'guard-shell'
63
+ gem.add_development_dependency 'guard-yard'
64
+ gem.add_development_dependency 'guard-rubocop'
65
+ gem.add_development_dependency 'guard-foodcritic'
66
+ gem.add_development_dependency 'guard-kitchen'
67
+ gem.add_development_dependency 'guard-rspec'
68
+ gem.add_development_dependency 'ruby_gntp'
69
+
70
+ # Integration gems
71
+ gem.add_development_dependency 'test-kitchen', '~> 1.3'
72
+ gem.add_development_dependency 'kitchen-vagrant'
73
+ gem.add_development_dependency 'vagrant-wrapper'
74
+ gem.add_development_dependency 'kitchen-docker'
75
+ gem.add_development_dependency 'kitchen-sync'
76
+ gem.add_development_dependency 'rubocop'
77
+ gem.add_development_dependency 'geminabox-rake'
78
+
79
+ # Versioning
80
+ gem.add_development_dependency 'version'
81
+ gem.add_development_dependency 'thor-scmversion'
82
+ gem.add_development_dependency 'semverse'
83
+ end
@@ -0,0 +1,290 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ # ____ ____ ____ __ ___ ____
21
+ # / T / T| \ / ] / \ | \
22
+ # Y __jY o || D ) / / Y Y| _ Y
23
+ # | T || || / / / | O || | |
24
+ # | l_ || _ || \ / \_ | || | |
25
+ # | || | || . Y\ |l !| | |
26
+ # l___,_jl__j__jl__j\_j \____j \___/ l__j__j
27
+
28
+ require 'chef/recipe'
29
+ require 'chef/resource'
30
+ require 'chef/provider'
31
+
32
+ require_relative 'garcon/version'
33
+ require_relative 'garcon/configuration'
34
+ require_relative 'garcon/exceptions'
35
+ require_relative 'garcon/inflections'
36
+ require_relative 'garcon/secret'
37
+ require_relative 'garcon/stash/store'
38
+ require_relative 'garcon/core_ext'
39
+ require_relative 'garcon/task'
40
+ require_relative 'garcon/utils'
41
+
42
+ # Pirla o Sfigato Magnà Capo Fregna
43
+
44
+ module Garcon
45
+ # Extends base class or a module with garcon methods, called when module is
46
+ # included, extends the object with class and instance methods.
47
+ #
48
+ # @param [Object] object
49
+ # The object including Garcon
50
+ #
51
+ # @return [self]
52
+ #
53
+ # @api private
54
+ def self.included(object)
55
+ super
56
+ if Class === object
57
+ object.send(:include, ClassInclusions) # TODO fix this...
58
+ else
59
+ object.extend(ModuleExtensions)
60
+ end
61
+ end
62
+ private_class_method :included
63
+
64
+ # Extends an object with garcon extensions, called when module is extended,
65
+ # extends the object with class and instance methods.
66
+ #
67
+ # @param [Object] object
68
+ # The object including Garcon.
69
+ #
70
+ # @return [self]
71
+ #
72
+ # @api private
73
+ def self.extended(object)
74
+ object.extend(Extensions)
75
+ end
76
+ private_class_method :extended
77
+
78
+ # Sets the global Crypto configuration.
79
+ #
80
+ # @example
81
+ # Garcon.config do |c|
82
+ # c.crypto.password = "!mWh0!s@y!m"
83
+ # c.crypto.salt = "9e5f851900cad8892ac8b737b7370cbe"
84
+ # end
85
+ #
86
+ # @return [Garcon::Crypto]
87
+ #
88
+ # @api public
89
+ def self.crypto(&block)
90
+ configuration.crypto(&block)
91
+ end
92
+
93
+ # Sets the global Crypto configuration value.
94
+ #
95
+ # @param [Boolean] value
96
+ #
97
+ # @return [Garcon::Crypto]
98
+ #
99
+ # @api public
100
+ def self.crypto=(value)
101
+ configuration.crypto = value
102
+ self
103
+ end
104
+
105
+ # Returns the global Crypto setting.
106
+ #
107
+ # @return [Boolean]
108
+ #
109
+ # @api public
110
+ def self.crypto
111
+ configuration.crypto
112
+ end
113
+
114
+ # Sets the global Secret configuration.
115
+ #
116
+ # @return [Garcon::Secret]
117
+ #
118
+ # @api public
119
+ def self.secret(&block)
120
+ configuration.secret(&block)
121
+ end
122
+
123
+ # Sets the global Secret configuration value.
124
+ #
125
+ # @param [Boolean] value
126
+ #
127
+ # @return [Garcon::Secret]
128
+ #
129
+ # @api public
130
+ def self.secret=(value)
131
+ configuration.secret = value
132
+ self
133
+ end
134
+
135
+ # Returns the global Secret setting.
136
+ #
137
+ # @return [Boolean]
138
+ #
139
+ # @api public
140
+ def self.secret
141
+ configuration.secret
142
+ end
143
+
144
+ # Provides access to the global Garcon configuration
145
+ #
146
+ # @example
147
+ # Garcon.config do |config|
148
+ # config.blender = true
149
+ # end
150
+ #
151
+ # @return [Configuration]
152
+ #
153
+ # @api public
154
+ def self.config(&block)
155
+ yield configuration if block_given?
156
+ configuration
157
+ end
158
+
159
+ # Global configuration instance.
160
+ #
161
+ # @return [Configuration]
162
+ #
163
+ # @api private
164
+ def self.configuration
165
+ @configuration ||= Configuration.new
166
+ end
167
+
168
+ # Defines if global executors should be auto-terminated with an `at_exit`
169
+ # callback. When set to `false` it will be the application programmer's
170
+ # responsibility to ensure that the global thread pools are shutdown properly
171
+ # prior to application exit.
172
+ #
173
+ def self.disable_auto_termination_of_global_executors!
174
+ Garcon.config.auto_terminate_global_executors.make_false
175
+ end
176
+ #
177
+ # @return [Boolean]
178
+ # true when global thread pools will auto-terminate on application exit
179
+ # using an `at_exit` handler; false when no auto-termination will occur.
180
+ #
181
+ def self.auto_terminate_global_executors?
182
+ Garcon.config.auto_terminate_global_executors.value
183
+ end
184
+
185
+ # Defines if *ALL* executors should be auto-terminated with an `at_exit`
186
+ # callback. When set to `false` it will be the application programmer's
187
+ # responsibility to ensure that *all* thread pools, including the global
188
+ # thread pools, are shutdown properly prior to application exit.
189
+ #
190
+ def self.disable_auto_termination_of_all_executors!
191
+ Garcon.config.auto_terminate_all_executors.make_false
192
+ end
193
+
194
+ # @return [Boolean]
195
+ # true when *all* thread pools will auto-terminate on application exit
196
+ # using an `at_exit` handler; false when no auto-termination will occur.
197
+ #
198
+ def self.auto_terminate_all_executors?
199
+ Garcon.config.auto_terminate_all_executors.value
200
+ end
201
+
202
+ # Global thread pool optimized for short, fast *operations*.
203
+ #
204
+ # @return [ThreadPoolExecutor] the thread pool
205
+ def self.global_fast_executor
206
+ Garcon.config.global_fast_executor.value
207
+ end
208
+
209
+ # Global thread pool optimized for long, blocking (IO) *tasks*.
210
+ #
211
+ # @return [ThreadPoolExecutor] the thread pool
212
+ def self.global_io_executor
213
+ Garcon.config.global_io_executor.value
214
+ end
215
+
216
+ # Global thread pool user for global *timers*.
217
+ #
218
+ # @return [Garcon::TimerSet] the thread pool
219
+ #
220
+ # @see Garcon::timer
221
+ def self.global_timer_set
222
+ Garcon.config.global_timer_set.value
223
+ end
224
+
225
+ def self.shutdown_global_executors
226
+ global_fast_executor.shutdown
227
+ global_io_executor.shutdown
228
+ global_timer_set.shutdown
229
+ end
230
+
231
+ def self.kill_global_executors
232
+ global_fast_executor.kill
233
+ global_io_executor.kill
234
+ global_timer_set.kill
235
+ end
236
+
237
+ def self.wait_for_global_executors_termination(timeout = nil)
238
+ latch = CountDownLatch.new(3)
239
+ [ global_fast_executor, global_io_executor, global_timer_set ].each do |ex|
240
+ Thread.new { ex.wait_for_termination(timeout); latch.count_down }
241
+ end
242
+ latch.wait(timeout)
243
+ end
244
+
245
+ def self.new_fast_executor(opts = {})
246
+ FixedThreadPool.new(
247
+ [2, Garcon.processor_count].max,
248
+ stop_on_exit: opts.fetch(:stop_on_exit, true),
249
+ idletime: 60, # 1 minute
250
+ max_queue: 0, # unlimited
251
+ fallback_policy: :caller_runs # shouldn't matter -- 0 max queue
252
+ )
253
+ end
254
+
255
+ def self.new_io_executor(opts = {})
256
+ ThreadPoolExecutor.new(
257
+ min_threads: [2, Garcon.processor_count].max,
258
+ max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE,
259
+ stop_on_exit: opts.fetch(:stop_on_exit, true),
260
+ idletime: 60, # 1 minute
261
+ max_queue: 0, # unlimited
262
+ fallback_policy: :caller_runs # shouldn't matter -- 0 max queue
263
+ )
264
+ end
265
+
266
+ # @return [String] object inspection
267
+ # @api public
268
+ def inspect
269
+ instance_variables.inject([
270
+ "\n#<#{self.class}:0x#{object_id.to_s(16)}>",
271
+ "\tInstance variables:"
272
+ ]) do |result, item|
273
+ result << "\t\t#{item} = #{instance_variable_get(item)}"
274
+ result
275
+ end.join("\n")
276
+ end
277
+
278
+ # @return [String] string of instance
279
+ # @api public
280
+ def to_s
281
+ "<#{self.class}:0x#{object_id.to_s(16)}>"
282
+ end
283
+
284
+ # @api private
285
+ def self.warn(msg)
286
+ Kernel.warn(msg)
287
+ end
288
+ end
289
+
290
+ require_relative 'garcon/chef_inclusions'
@@ -0,0 +1,343 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ # More sweetness syntactical sugar for our Pâtissier.
22
+ #
23
+ module ChefHelpers
24
+ # Methods are also available as module-level methods as well as a mixin.
25
+ extend self
26
+
27
+ include Chef::Mixin::ShellOut
28
+ include Garcon::Exceptions
29
+
30
+ # def chef_run_context
31
+ # ::Chef::RunContext.new(chef_node, nil, nil)
32
+ # end
33
+ #
34
+ # TODO - ARE THESE CAUSING TROUBLE???
35
+ #
36
+ # def chef_node
37
+ # node = ::Chef::Node.new
38
+ # node.consume_external_attrs(nil, ohai)
39
+ # node
40
+ # end
41
+
42
+ # Boolean indicating if the given Ruby Gem is installed.
43
+ #
44
+ # @param [String] gem
45
+ # The name of the Ruby Gem to check for.
46
+ #
47
+ # @return [Boolean]
48
+ # True if the Ruby Gem is installed, otherwise false.
49
+ #
50
+ def gem_installed?(gem = name)
51
+ Gem::Specification.find_all_by_name(gem).blank? ? false : true
52
+ end
53
+
54
+ # Search for a matching node by a given role or tag.
55
+ #
56
+ # @param [Symbol] type
57
+ # The filter type, can be `:role` or `:tag`.
58
+ #
59
+ # @param [String] filter
60
+ # The role or tag to filter on.
61
+ #
62
+ # @param [Boolean] single
63
+ # True if we should return only a single match, or false to return all
64
+ # of the matches.
65
+ #
66
+ # @yield an optional block to enumerate over the nodes.
67
+ #
68
+ # @return [Array, Proc]
69
+ # The value of the passed block or node.
70
+ #
71
+ # @api public
72
+ def find_by(type, filter, single = true, &block)
73
+ nodes = []
74
+ env = node.chef_environment
75
+ if node.public_send(Inflections.pluralize(type.to_s)).include? filter
76
+ nodes << node
77
+ end
78
+ if !single || nodes.empty?
79
+ search(:node, "#{type}:#{filter} AND chef_environment:#{env}") do |n|
80
+ nodes << n
81
+ end
82
+ end
83
+
84
+ if block_given?
85
+ nodes.each { |n| yield n }
86
+ else
87
+ single ? nodes.first : nodes
88
+ end
89
+ end
90
+
91
+ # Search for a matching node by role.
92
+ #
93
+ # @param [String] role
94
+ # The role to filter on.
95
+ #
96
+ # @param [Boolean] single
97
+ # True if we should return only a single match, or false to return all
98
+ # of the matches.
99
+ #
100
+ # @yield an optional block to enumerate over the nodes.
101
+ #
102
+ # @return [Array, Proc]
103
+ # The value of the passed block or node.
104
+ #
105
+ # @api public
106
+ def find_by_role(role, single = true, &block)
107
+ find_matching :role, role, single, block
108
+ end
109
+
110
+ # Search for a matching node by tag.
111
+ #
112
+ # @param [String] tag
113
+ # The role or tag to filter on.
114
+ #
115
+ # @param [Boolean] single
116
+ # True if we should return only a single match, or false to return all
117
+ # of the matches.
118
+ #
119
+ # @yield an optional block to enumerate over the nodes.
120
+ #
121
+ # @return [Array, Proc]
122
+ # The value of the passed block or node.
123
+ #
124
+ # @api public
125
+ def find_by_tag(tag, single = true, &block)
126
+ find_matching :tag, tag, single, block
127
+ end
128
+
129
+ alias_method :find_matching, :find_by
130
+ alias_method :find_matching_role, :find_by_role
131
+ alias_method :find_matching_tag, :find_by_tag
132
+
133
+ # Adds a `run_now` method onto Resources so you can immediately execute
134
+ # the resource block. This is a shortcut so you do not have to set the
135
+ # action to :nothing, and then use the `.run_action` method with the
136
+ # desired action.
137
+ #
138
+ # @example
139
+ # service 'sshd' do
140
+ # action [:enable, :start]
141
+ # end.run_now
142
+ #
143
+ def run_now(resource = nil)
144
+ resource ||= self
145
+ actions = Array(resource.action)
146
+ Chef::Log.debug "Immediate execution of #{resource.name} #{actions}"
147
+ resource.action(:nothing)
148
+ actions.each { |action| resource.run_action(action) }
149
+ end
150
+
151
+ # Returns true if the current node is a docker container, otherwise
152
+ # false.
153
+ #
154
+ # @return [Boolean]
155
+ #
156
+ # @api public
157
+ def docker?
158
+ ::File.exist?('/.dockerinit') || ::File.exist?('/.dockerenv')
159
+ end
160
+
161
+ # Returns true if the current node has selinux enabled, otherwise false.
162
+ #
163
+ # @return [Boolean]
164
+ #
165
+ # @api public
166
+ def selinux?
167
+ if installed?('getenforce')
168
+ Mixlib::ShellOut.new('getenforce').run_command.stdout != "Disabled\n"
169
+ else
170
+ false
171
+ end
172
+ end
173
+
174
+ # Retrieve the version number of the cookbook in the run list.
175
+ #
176
+ # @param name [String]
177
+ # name of cookbook to retrieve the version on.
178
+ #
179
+ # @return [Integer]
180
+ # version of the cookbook.
181
+ #
182
+ # @api public
183
+ def cookbook_version(name = nil)
184
+ cookbook = name.nil? ? cookbook_name : name
185
+ node.run_context.cookbook_collection[cookbook].metadata.version
186
+ end
187
+
188
+ # Shortcut to return cache path, if you pass in a file it will return
189
+ # the file with the cache path.
190
+ #
191
+ # @example
192
+ # file_cache_path
193
+ # => "/var/chef/cache/"
194
+ #
195
+ # file_cache_path 'patch.tar.gz'
196
+ # => "/var/chef/cache/patch.tar.gz"
197
+ #
198
+ # file_cache_path "#{node[:name]}-backup.tar.gz"
199
+ # => "/var/chef/cache/c20d24209cc8-backup.tar.gz"
200
+ #
201
+ # @param [String] args
202
+ # name of file to return path with file
203
+ #
204
+ # @return [String]
205
+ #
206
+ # @api public
207
+ def file_cache_path(*args)
208
+ if args.nil?
209
+ Chef::Config[:file_cache_path]
210
+ else
211
+ ::File.join(Chef::Config[:file_cache_path], args)
212
+ end
213
+ end
214
+
215
+ # Invokes the public method whose name goes as first argument just like
216
+ # `public_send` does, except that if the receiver does not respond to
217
+ # it the call returns `nil` rather than raising an exception.
218
+ #
219
+ # @note `_?` is defined on `Object`. Therefore, it won't work with
220
+ # instances of classes that do not have `Object` among their ancestors,
221
+ # like direct subclasses of `BasicObject`.
222
+ #
223
+ # @param [String] object
224
+ # The object to send the method to.
225
+ #
226
+ # @param [Symbol] method
227
+ # The method to send to the object.
228
+ #
229
+ # @api public
230
+ def _?(*args, &block)
231
+ if args.empty? && block_given?
232
+ yield self
233
+ else
234
+ resp = public_send(*args[0], &block) if respond_to?(args.first)
235
+ return nil if resp.nil?
236
+ !!resp == resp ? args[1] : [args[1], resp]
237
+ end
238
+ end
239
+
240
+ # Checks for existence of a cookbook file or template source in a cookbook.
241
+ #
242
+ # @example
243
+ # has_source?("foo.erb", :templates)
244
+ # has_source?("bar.conf", :files, "a_cookbook")
245
+ #
246
+ # @param [String] source
247
+ # Name of the desired template or cookbook file source.
248
+ #
249
+ # @param [Symbol] segment
250
+ # One of `:files` or `:templates`.
251
+ #
252
+ # @param [String, Nil] cookbook
253
+ # The name of the cookbook to look in, defaults to current cookbook.
254
+ #
255
+ # @return [String, Nil]
256
+ # Full path to the source or nil if it doesn't exist.
257
+ #
258
+ def has_source?(source, segment, cookbook = nil)
259
+ cookbook ||= cookbook_name
260
+ begin
261
+ run_context.cookbook_collection[cookbook].send(
262
+ :find_preferred_manifest_record, run_context.node, segment, source
263
+ )
264
+ rescue Chef::Exceptions::FileNotFound
265
+ nil
266
+ end
267
+ end
268
+
269
+ # Returns a hash using col1 as keys and col2 as values.
270
+ #
271
+ # @example zip_hash([:name, :age, :sex], ['Earl', 30, 'male'])
272
+ # => { :age => 30, :name => "Earl", :sex => "male" }
273
+ #
274
+ # @param [Array] col1
275
+ # Containing the keys.
276
+ #
277
+ # @param [Array] col2
278
+ # Values for hash.
279
+ #
280
+ # @return [Hash]
281
+ #
282
+ def zip_hash(col1, col2)
283
+ col1.zip(col2).inject({}) { |r, i| r[i[0]] = i[1]; r }
284
+ end
285
+
286
+ # Amazingly and somewhat surprisingly comma separate a number
287
+ #
288
+ # @param [Integer] num
289
+ #
290
+ # @return [String]
291
+ #
292
+ # @api public
293
+ def comma_separate(num)
294
+ num.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
295
+ end
296
+
297
+ # Creates a temp directory executing the block provided. When done the
298
+ # temp directory and all it's contents are garbage collected.
299
+ #
300
+ # @yield [Proc] block
301
+ # A block that will be run
302
+ #
303
+ # @return [Object]
304
+ # Result of the block operation
305
+ #
306
+ # @api public
307
+ def with_tmp_dir(&block)
308
+ Dir.mktmpdir(SecureRandom.hex(3)) do |tmp_dir|
309
+ Dir.chdir(tmp_dir, &block)
310
+ end
311
+ end
312
+
313
+ # Boolean method to check if a command line utility is installed.
314
+ #
315
+ # @param [String] cmd
316
+ # the command to find
317
+ #
318
+ # @return [TrueClass, FalseClass]
319
+ # true if the command is found in the path, false otherwise
320
+ #
321
+ def installed?(cmd)
322
+ !Garcon::FileHelper.which(cmd).nil?
323
+ end
324
+
325
+ # @return [String] object inspection
326
+ # @api public
327
+ def inspect
328
+ instance_variables.inject([
329
+ "\n#<#{self.class}:0x#{self.object_id.to_s(16)}>",
330
+ "\tInstance variables:"
331
+ ]) do |result, item|
332
+ result << "\t\t#{item} = #{instance_variable_get(item)}"
333
+ result
334
+ end.join("\n")
335
+ end
336
+
337
+ # @return [String] string of instance
338
+ # @api public
339
+ def to_s
340
+ "<#{self.class}:0x#{self.object_id.to_s(16)}>"
341
+ end
342
+ end
343
+ end