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.
- 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
|