loom-core 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +99 -0
- data/Guardfile +54 -0
- data/Rakefile +6 -0
- data/bin/loom +185 -0
- data/lib/env/development.rb +1 -0
- data/lib/loom.rb +44 -0
- data/lib/loom/all.rb +20 -0
- data/lib/loom/config.rb +106 -0
- data/lib/loom/core_ext.rb +37 -0
- data/lib/loom/dsl.rb +60 -0
- data/lib/loom/facts.rb +13 -0
- data/lib/loom/facts/all.rb +2 -0
- data/lib/loom/facts/fact_file_provider.rb +86 -0
- data/lib/loom/facts/fact_set.rb +138 -0
- data/lib/loom/host_spec.rb +32 -0
- data/lib/loom/inventory.rb +124 -0
- data/lib/loom/logger.rb +141 -0
- data/lib/loom/method_signature.rb +174 -0
- data/lib/loom/mods.rb +4 -0
- data/lib/loom/mods/action_proxy.rb +105 -0
- data/lib/loom/mods/all.rb +3 -0
- data/lib/loom/mods/mod_loader.rb +80 -0
- data/lib/loom/mods/module.rb +113 -0
- data/lib/loom/pattern.rb +15 -0
- data/lib/loom/pattern/all.rb +7 -0
- data/lib/loom/pattern/definition_context.rb +74 -0
- data/lib/loom/pattern/dsl.rb +176 -0
- data/lib/loom/pattern/hook.rb +28 -0
- data/lib/loom/pattern/loader.rb +48 -0
- data/lib/loom/pattern/reference.rb +71 -0
- data/lib/loom/pattern/reference_set.rb +169 -0
- data/lib/loom/pattern/result_reporter.rb +77 -0
- data/lib/loom/runner.rb +209 -0
- data/lib/loom/shell.rb +12 -0
- data/lib/loom/shell/all.rb +10 -0
- data/lib/loom/shell/api.rb +48 -0
- data/lib/loom/shell/cmd_result.rb +33 -0
- data/lib/loom/shell/cmd_wrapper.rb +164 -0
- data/lib/loom/shell/core.rb +226 -0
- data/lib/loom/shell/harness_blob.rb +26 -0
- data/lib/loom/shell/harness_command_builder.rb +50 -0
- data/lib/loom/shell/session.rb +25 -0
- data/lib/loom/trap.rb +44 -0
- data/lib/loom/version.rb +3 -0
- data/lib/loomext/all.rb +4 -0
- data/lib/loomext/corefacts.rb +6 -0
- data/lib/loomext/corefacts/all.rb +8 -0
- data/lib/loomext/corefacts/facter_provider.rb +24 -0
- data/lib/loomext/coremods.rb +5 -0
- data/lib/loomext/coremods/all.rb +13 -0
- data/lib/loomext/coremods/exec.rb +50 -0
- data/lib/loomext/coremods/files.rb +104 -0
- data/lib/loomext/coremods/net.rb +33 -0
- data/lib/loomext/coremods/package/adapter.rb +100 -0
- data/lib/loomext/coremods/package/package.rb +62 -0
- data/lib/loomext/coremods/user.rb +82 -0
- data/lib/loomext/coremods/vm.rb +0 -0
- data/lib/loomext/coremods/vm/all.rb +6 -0
- data/lib/loomext/coremods/vm/vbox.rb +84 -0
- data/loom.gemspec +39 -0
- data/loom/inventory.yml +13 -0
- data/scripts/harness.sh +242 -0
- data/spec/loom/host_spec_spec.rb +101 -0
- data/spec/loom/inventory_spec.rb +154 -0
- data/spec/loom/method_signature_spec.rb +275 -0
- data/spec/loom/pattern/dsl_spec.rb +207 -0
- data/spec/loom/shell/cmd_wrapper_spec.rb +239 -0
- data/spec/loom/shell/harness_blob_spec.rb +42 -0
- data/spec/loom/shell/harness_command_builder_spec.rb +36 -0
- data/spec/runloom.sh +35 -0
- data/spec/scripts/harness_spec.rb +385 -0
- data/spec/spec_helper.rb +94 -0
- data/spec/test.loom +370 -0
- data/spec/test_loom_spec.rb +57 -0
- metadata +287 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '00595d8a3c27f3c3a2567849e6d188c68a3c5914646238f0009767bff5769687'
|
4
|
+
data.tar.gz: 1988e1d88027c87309183db5355a2167f46ef2c48efcde7d5d143daf04011ea3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a48f5d6d82ec87da2c8e0dca0107602a434f8e4d8f42e1eb5d4d5638106aea1733836745d91db52f497b0eb4d2b9812909a42e9aef10a6408a26b23cb227758c
|
7
|
+
data.tar.gz: dc23a63efd9405c7834911e66a709f944793e8b9bca62858e0a86864f999d0d8e942a21f9bda9893bd2672291806205d0b7e752cb9dbe70e0b2854630434bb97
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
loom-core (0.0.1)
|
5
|
+
bcrypt_pbkdf (= 1.0.0.alpha1)
|
6
|
+
commander (~> 4.4)
|
7
|
+
net-ssh (>= 3)
|
8
|
+
rbnacl-libsodium (= 1.0.10)
|
9
|
+
sshkit (~> 1.11)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
bcrypt_pbkdf (1.0.0.alpha1)
|
15
|
+
byebug (9.0.6)
|
16
|
+
coderay (1.1.1)
|
17
|
+
commander (4.4.0)
|
18
|
+
highline (~> 1.7.2)
|
19
|
+
diff-lcs (1.2.5)
|
20
|
+
ffi (1.9.14)
|
21
|
+
formatador (0.2.5)
|
22
|
+
guard (2.14.0)
|
23
|
+
formatador (>= 0.2.4)
|
24
|
+
listen (>= 2.7, < 4.0)
|
25
|
+
lumberjack (~> 1.0)
|
26
|
+
nenv (~> 0.1)
|
27
|
+
notiffany (~> 0.0)
|
28
|
+
pry (>= 0.9.12)
|
29
|
+
shellany (~> 0.0)
|
30
|
+
thor (>= 0.18.1)
|
31
|
+
guard-compat (1.2.1)
|
32
|
+
guard-rspec (4.7.3)
|
33
|
+
guard (~> 2.1)
|
34
|
+
guard-compat (~> 1.1)
|
35
|
+
rspec (>= 2.99.0, < 4.0)
|
36
|
+
highline (1.7.8)
|
37
|
+
listen (3.1.5)
|
38
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
39
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
40
|
+
ruby_dep (~> 1.2)
|
41
|
+
lumberjack (1.0.10)
|
42
|
+
method_source (0.8.2)
|
43
|
+
nenv (0.3.0)
|
44
|
+
net-scp (1.2.1)
|
45
|
+
net-ssh (>= 2.6.5)
|
46
|
+
net-ssh (3.2.0)
|
47
|
+
notiffany (0.1.1)
|
48
|
+
nenv (~> 0.1)
|
49
|
+
shellany (~> 0.0)
|
50
|
+
pry (0.10.4)
|
51
|
+
coderay (~> 1.1.0)
|
52
|
+
method_source (~> 0.8.1)
|
53
|
+
slop (~> 3.4)
|
54
|
+
pry-byebug (3.4.0)
|
55
|
+
byebug (~> 9.0)
|
56
|
+
pry (~> 0.10)
|
57
|
+
rake (11.3.0)
|
58
|
+
rb-fsevent (0.9.8)
|
59
|
+
rb-inotify (0.9.7)
|
60
|
+
ffi (>= 0.5.0)
|
61
|
+
rbnacl (3.4.0)
|
62
|
+
ffi
|
63
|
+
rbnacl-libsodium (1.0.10)
|
64
|
+
rbnacl (>= 3.0.1)
|
65
|
+
rspec (3.5.0)
|
66
|
+
rspec-core (~> 3.5.0)
|
67
|
+
rspec-expectations (~> 3.5.0)
|
68
|
+
rspec-mocks (~> 3.5.0)
|
69
|
+
rspec-core (3.5.4)
|
70
|
+
rspec-support (~> 3.5.0)
|
71
|
+
rspec-expectations (3.5.0)
|
72
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
73
|
+
rspec-support (~> 3.5.0)
|
74
|
+
rspec-mocks (3.5.0)
|
75
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
76
|
+
rspec-support (~> 3.5.0)
|
77
|
+
rspec-support (3.5.0)
|
78
|
+
ruby_dep (1.5.0)
|
79
|
+
shellany (0.0.1)
|
80
|
+
slop (3.6.0)
|
81
|
+
sshkit (1.11.4)
|
82
|
+
net-scp (>= 1.1.2)
|
83
|
+
net-ssh (>= 2.8.0)
|
84
|
+
thor (0.19.1)
|
85
|
+
|
86
|
+
PLATFORMS
|
87
|
+
ruby
|
88
|
+
|
89
|
+
DEPENDENCIES
|
90
|
+
bundler (~> 1.13)
|
91
|
+
guard-rspec (~> 4.7)
|
92
|
+
loom-core!
|
93
|
+
pry (~> 0.10)
|
94
|
+
pry-byebug
|
95
|
+
rake (~> 11.3)
|
96
|
+
rspec (~> 3.5)
|
97
|
+
|
98
|
+
BUNDLED WITH
|
99
|
+
1.13.6
|
data/Guardfile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Explicitly speficy emacs in order to disable notify-send notifications
|
32
|
+
notification :emacs
|
33
|
+
|
34
|
+
# Feel free to open issues for suggestions and improvements
|
35
|
+
|
36
|
+
# RSpec files
|
37
|
+
rspec = dsl.rspec
|
38
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
39
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
40
|
+
watch(rspec.spec_files)
|
41
|
+
|
42
|
+
# Ruby files
|
43
|
+
ruby = dsl.ruby
|
44
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
45
|
+
|
46
|
+
# Loom shell scripts
|
47
|
+
watch(%r{^scripts/(.+)\.sh$}) { |m| "spec/scripts/#{m[1]}_spec.rb" }
|
48
|
+
|
49
|
+
# Turnip features and steps
|
50
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
51
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
52
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
53
|
+
end
|
54
|
+
end
|
data/Rakefile
ADDED
data/bin/loom
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
if __FILE__ == $0
|
3
|
+
# for local development, when running bin/loom directly
|
4
|
+
$: << 'lib'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'commander'
|
8
|
+
require 'loom'
|
9
|
+
|
10
|
+
Loom.configure do |c|
|
11
|
+
c.log_level = :info
|
12
|
+
end
|
13
|
+
|
14
|
+
module Loom
|
15
|
+
class Cli
|
16
|
+
include Commander::Methods
|
17
|
+
|
18
|
+
def run
|
19
|
+
program :name, "Loom - Weaving through infrastructure"
|
20
|
+
program :version , Loom::VERSION
|
21
|
+
program :description, <<EOS
|
22
|
+
A lightweight infrastructure managment tool designed to manage hosts
|
23
|
+
through SSH, loosely inspired by Python Fabric - http://www.fabfile.org/.
|
24
|
+
|
25
|
+
Try `loom weave uptime -H localhost` to see an example.
|
26
|
+
EOS
|
27
|
+
|
28
|
+
global_option "-V", "--verbose", "Report verbose results" do |v|
|
29
|
+
Loom.configure do |c|
|
30
|
+
c.run_verbose = v
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
global_option "-d", "Enable loom debug logging, implies --verbose" do |d|
|
35
|
+
Loom.configure do |c|
|
36
|
+
c.log_level = :debug
|
37
|
+
c.run_verbose = true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
global_option "--dbg [N]", Integer,
|
42
|
+
"Enable deep debug logging, where N is 0-6, implies --verbose" do |n|
|
43
|
+
raise "N must be greater than 0" if n < 0
|
44
|
+
Loom.configure do |c|
|
45
|
+
c.log_level = n * -1
|
46
|
+
c.run_verbose = true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
global_option "-l", "--loom-files file1,f2,f3", Array,
|
51
|
+
"Load loom files from FILES instead of from the search path." do |files|
|
52
|
+
Loom.configure { |c| c.loom_files = files }
|
53
|
+
end
|
54
|
+
|
55
|
+
global_option "-a", "--all-hosts",
|
56
|
+
"Adds all known hostnames to the active inventory, " +
|
57
|
+
"can be combined with -H for additional hosts" do |flag|
|
58
|
+
Loom.configure { |c| c.inventory_all_hosts = flag }
|
59
|
+
end
|
60
|
+
|
61
|
+
global_option "-H", "--hosts host1,h2,h3", Array,
|
62
|
+
"Adds HOSTS to the active inventory" do |hosts|
|
63
|
+
Loom.configure { |c| c.inventory_hosts = hosts }
|
64
|
+
end
|
65
|
+
|
66
|
+
global_option "-G", "--groups group1,g2,g3", Array,
|
67
|
+
"Adds hostnames in GROUPS to the active inventory" do |groups|
|
68
|
+
Loom.configure { |c| c.inventory_groups = groups }
|
69
|
+
end
|
70
|
+
|
71
|
+
global_option "-X", "--custom-config KEY=VAL", String do |config_value|
|
72
|
+
key, val, *_rest = config_value.split "="
|
73
|
+
Loom.configure do |c|
|
74
|
+
c[key.to_sym] = val
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
default_command :weave
|
79
|
+
|
80
|
+
command :"weave" do |c|
|
81
|
+
c.syntax = "loom weave [pattern...] [options]"
|
82
|
+
c.description = "Applies the patterns to the active host inventory. " +
|
83
|
+
"This is the default."
|
84
|
+
|
85
|
+
c.option "-A", "--all",
|
86
|
+
"Run all loaded the patterns"
|
87
|
+
c.option "-n", "--dry-run",
|
88
|
+
"Don't run the patterns, only connect and log the expected patterns"
|
89
|
+
c.option "-F", "--fact F1=V1[,F2=V2,F3=V3]]]", "add custom fact"
|
90
|
+
|
91
|
+
c.action do |patterns, options|
|
92
|
+
if options.all
|
93
|
+
patterns = Loom::Pattern::Loader.load(Loom.config).slugs
|
94
|
+
end
|
95
|
+
|
96
|
+
other_facts = {}
|
97
|
+
if options.fact
|
98
|
+
fact_pairs = options.fact.split ","
|
99
|
+
fact_pairs.each do |pair|
|
100
|
+
key, val = pair.split "="
|
101
|
+
other_facts[key.to_sym] = val
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
runner = Loom::Runner.new Loom.config, patterns, other_facts
|
106
|
+
runner.run options.dry_run
|
107
|
+
end
|
108
|
+
end
|
109
|
+
alias_command :"w", :"weave"
|
110
|
+
|
111
|
+
command :"mods" do |c|
|
112
|
+
c.syntax = "loom mods [mod]"
|
113
|
+
c.description = "Prints the list of registered mods."
|
114
|
+
|
115
|
+
c.action do |mods, options|
|
116
|
+
puts "Loom mods are:"
|
117
|
+
puts ""
|
118
|
+
|
119
|
+
Loom::Mods::ModLoader.registered_mods.each do |name, aliases|
|
120
|
+
puts aliases.join(", ")
|
121
|
+
puts "\t#{name}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
command :"patterns" do |c|
|
127
|
+
c.syntax = "loom patterns [pattern]"
|
128
|
+
c.description = "Prints the list of known patterns."
|
129
|
+
|
130
|
+
c.option "--print", "Only print the space separted pattern names."
|
131
|
+
c.action do |patterns, options|
|
132
|
+
pattern_loader = Loom::Pattern::Loader.load Loom.config
|
133
|
+
pattern_slugs = pattern_loader.slugs
|
134
|
+
if options.print
|
135
|
+
puts pattern_slugs.join " "
|
136
|
+
return
|
137
|
+
end
|
138
|
+
|
139
|
+
puts "Loom patterns are:"
|
140
|
+
puts ""
|
141
|
+
|
142
|
+
max_slug_len = pattern_slugs.map(&:size).reduce(0) { |*args| args.max }
|
143
|
+
pattern_loader.patterns.each do |ref|
|
144
|
+
puts "\t#{ref.slug.ljust(max_slug_len)}\t#{ref.desc}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
alias_command :"p", :"patterns"
|
149
|
+
|
150
|
+
command :"config" do |c|
|
151
|
+
c.syntax = "loom config [options]"
|
152
|
+
c.description = "Print the config."
|
153
|
+
c.action do
|
154
|
+
puts Loom.config.to_yaml
|
155
|
+
end
|
156
|
+
end
|
157
|
+
alias_command :"c", :"config"
|
158
|
+
|
159
|
+
command :"inventory" do |c|
|
160
|
+
c.syntax = "loom inventory [options]"
|
161
|
+
c.description = "List all hosts in the inventory."
|
162
|
+
|
163
|
+
c.option "--active", <<EOS
|
164
|
+
Restricts to the hosts in the active inventory, useful to check which
|
165
|
+
hosts will be targeted with the config. Using with the -a flag is
|
166
|
+
equivalent to omitting --active.
|
167
|
+
EOS
|
168
|
+
|
169
|
+
c.action do |arg, options|
|
170
|
+
inventory = if options.active
|
171
|
+
Loom::Inventory::InventoryList.active_inventory Loom.config
|
172
|
+
else
|
173
|
+
Loom::Inventory::InventoryList.total_inventory Loom.config
|
174
|
+
end
|
175
|
+
puts inventory.hostnames.sort.to_yaml
|
176
|
+
end
|
177
|
+
end
|
178
|
+
alias_command :"i", :"inventory"
|
179
|
+
|
180
|
+
run!
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
Loom::Cli.new.run
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'pry'
|
data/lib/loom.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'env/development'
|
2
|
+
|
3
|
+
module Loom
|
4
|
+
|
5
|
+
LoomError = Class.new ::StandardError
|
6
|
+
ExecutionError = Class.new LoomError
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def configure(&block)
|
10
|
+
@config = Loom::Config.configure @config, &block
|
11
|
+
config_changed
|
12
|
+
end
|
13
|
+
|
14
|
+
def config
|
15
|
+
unless @config
|
16
|
+
@config = Loom::Config.configure
|
17
|
+
config_changed
|
18
|
+
end
|
19
|
+
@config
|
20
|
+
end
|
21
|
+
|
22
|
+
def reset_config
|
23
|
+
@config = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def log
|
27
|
+
@logger ||= config_logger
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def config_changed
|
32
|
+
SSHKit.config.output_verbosity = config.sshkit_log_level
|
33
|
+
SSHKit.config.default_runner = config.sshkit_execution_strategy
|
34
|
+
@logger = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def config_logger
|
38
|
+
@logger = Loom::Logger.configure config
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'loom/all'
|
data/lib/loom/all.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "sshkit"
|
2
|
+
|
3
|
+
require_relative "core_ext"
|
4
|
+
require_relative "method_signature"
|
5
|
+
require_relative "trap"
|
6
|
+
|
7
|
+
require_relative "logger"
|
8
|
+
require_relative "config"
|
9
|
+
|
10
|
+
require_relative "shell"
|
11
|
+
require_relative "host_spec"
|
12
|
+
require_relative "dsl"
|
13
|
+
|
14
|
+
require_relative "inventory"
|
15
|
+
require_relative "facts"
|
16
|
+
require_relative "pattern"
|
17
|
+
require_relative "mods"
|
18
|
+
require_relative "runner"
|
19
|
+
|
20
|
+
require_relative "version"
|
data/lib/loom/config.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Loom
|
5
|
+
|
6
|
+
ConfigError = Class.new Loom::LoomError
|
7
|
+
|
8
|
+
class Config
|
9
|
+
|
10
|
+
CONFIG_VARS = {
|
11
|
+
:loom_search_paths => ['/etc/loom', File.join(ENV['HOME'], '.loom'), './.loom'],
|
12
|
+
:loom_files => ['site.loom'],
|
13
|
+
|
14
|
+
:inventory_all_hosts => false,
|
15
|
+
:inventory_hosts => [],
|
16
|
+
:inventory_groups => [],
|
17
|
+
|
18
|
+
:log_level => :warn, # [debug, info, warn, error, fatal, or Integer]
|
19
|
+
:log_device => :stderr, # [stderr, stdout, file descriptor, or file name]
|
20
|
+
:log_colorize => true,
|
21
|
+
|
22
|
+
:run_failure_strategy => :exclude_host, # [exclude_host, fail_fast, cowboy]
|
23
|
+
:run_verbose => false,
|
24
|
+
|
25
|
+
:sshkit_execution_strategy => :sequence, # [sequence, parallel, groups]
|
26
|
+
:sshkit_log_level => :warn,
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
attr_reader *CONFIG_VARS.keys, :config_map
|
30
|
+
|
31
|
+
def initialize(**config_map)
|
32
|
+
config_map.each do |k,v|
|
33
|
+
# allows attr_reader methods from CONFIG_VAR to work
|
34
|
+
instance_variable_set :"@#{k}", v
|
35
|
+
end
|
36
|
+
|
37
|
+
@config_map = config_map
|
38
|
+
@file_manager = FileManager.new self
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](key)
|
42
|
+
@config_map[key]
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_yaml
|
46
|
+
@config_map.to_yaml
|
47
|
+
end
|
48
|
+
alias_method :dump, :to_yaml # aliased to dump for debugging purposes
|
49
|
+
|
50
|
+
def files
|
51
|
+
@file_manager
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
def configure(config=nil, &block)
|
56
|
+
# do NOT call Loom.log inside this block, the logger may not be
|
57
|
+
# configured, triggering an infinite recursion
|
58
|
+
|
59
|
+
map = config ? config.config_map : CONFIG_VARS.dup
|
60
|
+
config_struct = OpenStruct.new **map
|
61
|
+
yield config_struct if block_given?
|
62
|
+
Config.new config_struct.to_h
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
class FileManager
|
68
|
+
|
69
|
+
LOOM_FILE_PATTERNS = ["*.loom"]
|
70
|
+
|
71
|
+
def initialize(config)
|
72
|
+
@loom_search_paths = config.loom_search_paths
|
73
|
+
@loom_files = config.loom_files
|
74
|
+
end
|
75
|
+
|
76
|
+
def find(glob_patterns)
|
77
|
+
search_loom_paths(glob_patterns)
|
78
|
+
end
|
79
|
+
|
80
|
+
def loom_files
|
81
|
+
[@loom_files + search_loom_paths(LOOM_FILE_PATTERNS)].flatten.uniq
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
def search_loom_paths(file_patterns)
|
86
|
+
# Maps glob patterns into real file paths, selecting only
|
87
|
+
# readable files, and logs the result.
|
88
|
+
file_patterns.map do |file_pattern|
|
89
|
+
@loom_search_paths.map do |path|
|
90
|
+
Dir.glob File.join(path, "**", file_pattern)
|
91
|
+
end
|
92
|
+
end.flatten.uniq.select do |path|
|
93
|
+
should_select = File.file?(path) && File.readable?(path)
|
94
|
+
unless should_select
|
95
|
+
Loom.log.debug1(self) { "skipping config path => #{path}" }
|
96
|
+
end
|
97
|
+
should_select
|
98
|
+
end.tap do |config_files|
|
99
|
+
unless config_files.empty?
|
100
|
+
Loom.log.debug1(self) { "found config files => #{config_files}" }
|
101
|
+
end
|
102
|
+
end.uniq
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|