loom-core 0.0.1
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/.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
|