garcun 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +17 -0
- data/.gitignore +197 -0
- data/.rspec +2 -0
- data/Gemfile +22 -0
- data/LICENSE +201 -0
- data/README.md +521 -0
- data/Rakefile +47 -0
- data/garcun.gemspec +83 -0
- data/lib/garcon.rb +290 -0
- data/lib/garcon/chef/chef_helpers.rb +343 -0
- data/lib/garcon/chef/coerce/coercer.rb +134 -0
- data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
- data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
- data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
- data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
- data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
- data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
- data/lib/garcon/chef/handler/devreporter.rb +127 -0
- data/lib/garcon/chef/log.rb +64 -0
- data/lib/garcon/chef/node.rb +100 -0
- data/lib/garcon/chef/provider/civilize.rb +209 -0
- data/lib/garcon/chef/provider/development.rb +159 -0
- data/lib/garcon/chef/provider/download.rb +420 -0
- data/lib/garcon/chef/provider/house_keeping.rb +265 -0
- data/lib/garcon/chef/provider/node_cache.rb +31 -0
- data/lib/garcon/chef/provider/partial.rb +183 -0
- data/lib/garcon/chef/provider/recovery.rb +80 -0
- data/lib/garcon/chef/provider/zip_file.rb +271 -0
- data/lib/garcon/chef/resource/attribute.rb +52 -0
- data/lib/garcon/chef/resource/base_dsl.rb +174 -0
- data/lib/garcon/chef/resource/blender.rb +140 -0
- data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
- data/lib/garcon/chef/resource/resource_name.rb +109 -0
- data/lib/garcon/chef/secret_bag.rb +204 -0
- data/lib/garcon/chef/validations.rb +76 -0
- data/lib/garcon/chef_inclusions.rb +151 -0
- data/lib/garcon/configuration.rb +138 -0
- data/lib/garcon/core_ext.rb +39 -0
- data/lib/garcon/core_ext/array.rb +27 -0
- data/lib/garcon/core_ext/binding.rb +64 -0
- data/lib/garcon/core_ext/boolean.rb +66 -0
- data/lib/garcon/core_ext/duration.rb +271 -0
- data/lib/garcon/core_ext/enumerable.rb +34 -0
- data/lib/garcon/core_ext/file.rb +127 -0
- data/lib/garcon/core_ext/filetest.rb +62 -0
- data/lib/garcon/core_ext/hash.rb +279 -0
- data/lib/garcon/core_ext/kernel.rb +159 -0
- data/lib/garcon/core_ext/lazy.rb +222 -0
- data/lib/garcon/core_ext/method_access.rb +243 -0
- data/lib/garcon/core_ext/module.rb +92 -0
- data/lib/garcon/core_ext/nil.rb +53 -0
- data/lib/garcon/core_ext/numeric.rb +44 -0
- data/lib/garcon/core_ext/object.rb +342 -0
- data/lib/garcon/core_ext/pathname.rb +152 -0
- data/lib/garcon/core_ext/process.rb +41 -0
- data/lib/garcon/core_ext/random.rb +497 -0
- data/lib/garcon/core_ext/string.rb +312 -0
- data/lib/garcon/core_ext/struct.rb +49 -0
- data/lib/garcon/core_ext/symbol.rb +170 -0
- data/lib/garcon/core_ext/time.rb +234 -0
- data/lib/garcon/exceptions.rb +101 -0
- data/lib/garcon/inflections.rb +237 -0
- data/lib/garcon/inflections/defaults.rb +79 -0
- data/lib/garcon/inflections/inflections.rb +182 -0
- data/lib/garcon/inflections/rules_collection.rb +37 -0
- data/lib/garcon/secret.rb +271 -0
- data/lib/garcon/stash/format.rb +114 -0
- data/lib/garcon/stash/journal.rb +226 -0
- data/lib/garcon/stash/queue.rb +83 -0
- data/lib/garcon/stash/serializer.rb +86 -0
- data/lib/garcon/stash/store.rb +435 -0
- data/lib/garcon/task.rb +31 -0
- data/lib/garcon/task/atomic.rb +151 -0
- data/lib/garcon/task/atomic_boolean.rb +127 -0
- data/lib/garcon/task/condition.rb +99 -0
- data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
- data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
- data/lib/garcon/task/count_down_latch.rb +92 -0
- data/lib/garcon/task/delay.rb +196 -0
- data/lib/garcon/task/dereferenceable.rb +144 -0
- data/lib/garcon/task/event.rb +119 -0
- data/lib/garcon/task/executor.rb +275 -0
- data/lib/garcon/task/executor_options.rb +59 -0
- data/lib/garcon/task/future.rb +107 -0
- data/lib/garcon/task/immediate_executor.rb +84 -0
- data/lib/garcon/task/ivar.rb +171 -0
- data/lib/garcon/task/lazy_reference.rb +74 -0
- data/lib/garcon/task/monotonic_time.rb +69 -0
- data/lib/garcon/task/obligation.rb +256 -0
- data/lib/garcon/task/observable.rb +101 -0
- data/lib/garcon/task/priority_queue.rb +234 -0
- data/lib/garcon/task/processor_count.rb +128 -0
- data/lib/garcon/task/read_write_lock.rb +304 -0
- data/lib/garcon/task/safe_task_executor.rb +58 -0
- data/lib/garcon/task/single_thread_executor.rb +97 -0
- data/lib/garcon/task/thread_pool/cached.rb +71 -0
- data/lib/garcon/task/thread_pool/executor.rb +294 -0
- data/lib/garcon/task/thread_pool/fixed.rb +61 -0
- data/lib/garcon/task/thread_pool/worker.rb +90 -0
- data/lib/garcon/task/timer.rb +44 -0
- data/lib/garcon/task/timer_set.rb +194 -0
- data/lib/garcon/task/timer_task.rb +377 -0
- data/lib/garcon/task/waitable_list.rb +58 -0
- data/lib/garcon/utility/ansi.rb +199 -0
- data/lib/garcon/utility/at_random.rb +77 -0
- data/lib/garcon/utility/crypto.rb +292 -0
- data/lib/garcon/utility/equalizer.rb +146 -0
- data/lib/garcon/utility/faker/extensions/array.rb +22 -0
- data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
- data/lib/garcon/utility/faker/faker.rb +164 -0
- data/lib/garcon/utility/faker/faker/company.rb +17 -0
- data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
- data/lib/garcon/utility/faker/faker/version.rb +3 -0
- data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
- data/lib/garcon/utility/faker/locales/en.yml +21 -0
- data/lib/garcon/utility/file_helper.rb +170 -0
- data/lib/garcon/utility/hookers.rb +178 -0
- data/lib/garcon/utility/interpolation.rb +90 -0
- data/lib/garcon/utility/memstash.rb +364 -0
- data/lib/garcon/utility/misc.rb +54 -0
- data/lib/garcon/utility/msg_from_god.rb +62 -0
- data/lib/garcon/utility/retry.rb +238 -0
- data/lib/garcon/utility/timeout.rb +58 -0
- data/lib/garcon/utility/uber/builder.rb +91 -0
- data/lib/garcon/utility/uber/callable.rb +7 -0
- data/lib/garcon/utility/uber/delegates.rb +13 -0
- data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
- data/lib/garcon/utility/uber/options.rb +101 -0
- data/lib/garcon/utility/uber/uber_version.rb +3 -0
- data/lib/garcon/utility/uber/version.rb +33 -0
- data/lib/garcon/utility/url_helper.rb +100 -0
- data/lib/garcon/utils.rb +29 -0
- data/lib/garcon/version.rb +62 -0
- data/lib/garcun.rb +24 -0
- metadata +680 -0
data/Rakefile
ADDED
@@ -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
|
data/garcun.gemspec
ADDED
@@ -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
|
data/lib/garcon.rb
ADDED
@@ -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
|