garcun 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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