loom-core 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba730790e0a31bfadc0f837eb2574f9e21aed1833afd06881987cb76bc6bce2d
4
- data.tar.gz: 6e3936463bef27cf155cdd9873f0268547495d1e0609dce16e5e7089699bd8f5
3
+ metadata.gz: 6d528b08eb52c1ed7fca596af8d47b5e1869c5bd98d1bbeba9cb66c27dad3043
4
+ data.tar.gz: 1445b6f3d508a9be19d32f2aa9253e3e6f7b7eb9b771b73ea482b9b3ca07a846
5
5
  SHA512:
6
- metadata.gz: bd86c4cafa91fcf0032f214999be470547f198f930cf1b4ff50e1aba0948aa6d78133205f05c91c81aedc2f4809266398365a5b57d878c6655ad92dc5f349100
7
- data.tar.gz: a9338a3ff37ed372683af92825b196e5a6c0db4ba9fc14b75a345357dcc92474aeb3008058243e88f24d09e752dcde000551fc79f76bfe3a08c42facc0c426c5
6
+ metadata.gz: 93499a20ce6ba74bcf96dc84d6fbf2c1b1c3fd38901dd9f4c06e8f3ce04d6d44dde3176f1aa88b8becbda43b72b5e93767d7e088d8d4fb1c52e40e3b07212f9e
7
+ data.tar.gz: f3e2c5a3699f76c3e6d83d41286b421158c9ed2380714dbe2e54658c51c3a466832967f29d1e12601c63beaf2f59d8e83b0b03938cff43459d906e59018d4eec
@@ -1,22 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- loom-core (0.0.1)
5
- bcrypt_pbkdf (= 1.0.0.alpha1)
4
+ loom-core (0.0.3)
5
+ bcrypt_pbkdf (>= 1.0, < 2.0)
6
6
  commander (~> 4.4)
7
- net-ssh (>= 3)
7
+ ed25519 (>= 1.0, < 2.0)
8
+ net-ssh (>= 5)
8
9
  rbnacl-libsodium (= 1.0.10)
9
10
  sshkit (~> 1.11)
10
11
 
11
12
  GEM
12
13
  remote: https://rubygems.org/
13
14
  specs:
14
- bcrypt_pbkdf (1.0.0.alpha1)
15
+ bcrypt_pbkdf (1.0.0)
15
16
  byebug (9.0.6)
16
17
  coderay (1.1.1)
17
- commander (4.4.0)
18
+ commander (4.4.6)
18
19
  highline (~> 1.7.2)
19
20
  diff-lcs (1.2.5)
21
+ ed25519 (1.2.4)
20
22
  ffi (1.9.14)
21
23
  formatador (0.2.5)
22
24
  guard (2.14.0)
@@ -33,7 +35,7 @@ GEM
33
35
  guard (~> 2.1)
34
36
  guard-compat (~> 1.1)
35
37
  rspec (>= 2.99.0, < 4.0)
36
- highline (1.7.8)
38
+ highline (1.7.10)
37
39
  listen (3.1.5)
38
40
  rb-fsevent (~> 0.9, >= 0.9.4)
39
41
  rb-inotify (~> 0.9, >= 0.9.7)
@@ -43,7 +45,7 @@ GEM
43
45
  nenv (0.3.0)
44
46
  net-scp (1.2.1)
45
47
  net-ssh (>= 2.6.5)
46
- net-ssh (3.2.0)
48
+ net-ssh (5.0.2)
47
49
  notiffany (0.1.1)
48
50
  nenv (~> 0.1)
49
51
  shellany (~> 0.0)
@@ -58,7 +60,7 @@ GEM
58
60
  rb-fsevent (0.9.8)
59
61
  rb-inotify (0.9.7)
60
62
  ffi (>= 0.5.0)
61
- rbnacl (3.4.0)
63
+ rbnacl (5.0.0)
62
64
  ffi
63
65
  rbnacl-libsodium (1.0.10)
64
66
  rbnacl (>= 3.0.1)
@@ -78,7 +80,7 @@ GEM
78
80
  ruby_dep (1.5.0)
79
81
  shellany (0.0.1)
80
82
  slop (3.6.0)
81
- sshkit (1.11.4)
83
+ sshkit (1.17.0)
82
84
  net-scp (>= 1.1.2)
83
85
  net-ssh (>= 2.8.0)
84
86
  thor (0.19.1)
@@ -96,4 +98,4 @@ DEPENDENCIES
96
98
  rspec (~> 3.5)
97
99
 
98
100
  BUNDLED WITH
99
- 1.13.6
101
+ 1.16.2
@@ -83,8 +83,10 @@ module Loom::Facts
83
83
  end
84
84
 
85
85
  def get(fact_name)
86
- result = @fact_map[fact_name.to_sym]
87
- result.dup rescue result
86
+ v = @fact_map[fact_name.to_sym]
87
+ dup = v.dup rescue v
88
+ dup = FactSet.new(@host_spec, {}) if dup.nil?
89
+ dup.is_a?(Hash) ? FactSet.new(@host_spec, dup) : dup
88
90
  end
89
91
  alias_method :[], :get
90
92
 
@@ -4,6 +4,10 @@ module Loom::Facts
4
4
  # TODO: add documentation re: use of namespace in fact_set.rb
5
5
  attr_reader :fact_map, :namespace
6
6
 
7
+ # TODO: add a mechanism to check for prerequisites to enabling a fact provider, currently
8
+ # FacterProvider does this manually. At a minimum binaries required by the fact provider to
9
+ # collect info should be checked to be available.
10
+
7
11
  class << self
8
12
  def disable_for_host(host_spec, klass)
9
13
  Loom.log.warn "disabling fact provider => #{klass} on #{host_spec.hostname}"
@@ -2,6 +2,7 @@ require_relative "dsl"
2
2
  require_relative "hook"
3
3
  require_relative "definition_context"
4
4
  require_relative "reference"
5
+ require_relative "expanding_reference"
5
6
  require_relative "reference_set"
6
7
  require_relative "loader"
7
8
  require_relative "result_reporter"
@@ -49,6 +49,8 @@ module Loom::Pattern
49
49
  Hook.after_hooks merged_hooks.reverse
50
50
  end
51
51
 
52
+ # Helper methods for flattening all parent definition contexts for running a
53
+ # pattern ref.
52
54
  private
53
55
  def merged_fact_map
54
56
  merged_contexts.map(&:fact_map).reduce({}) do |merged_map, next_map|
@@ -62,6 +64,10 @@ module Loom::Pattern
62
64
  end
63
65
  end
64
66
 
67
+ ##
68
+ # Flattens the list of hooks from all parent modules so that executing the
69
+ # pattern reference executes all expected hooks in the correct order, w/o
70
+ # needing to recurse.
65
71
  def merged_hooks
66
72
  return hooks if @parent_context.nil?
67
73
  merged_contexts.map(&:hooks).flatten
@@ -98,6 +98,13 @@ Loom::Facts::FactSet as parameters.
98
98
 
99
99
  =end
100
100
  module Loom::Pattern
101
+
102
+ # TODO: clarify this DSL to only export:
103
+ # - description
104
+ # - pattern
105
+ # - let
106
+ # - after/before
107
+ # other methods are utility methods used to process and run patterns.
101
108
  module DSL
102
109
 
103
110
  loom_accessor :namespace
@@ -120,7 +127,23 @@ module Loom::Pattern
120
127
  end
121
128
 
122
129
  def pattern(name, &block)
123
- Loom.log.debug3(self) { "defined pattern method => #{name}" }
130
+ Loom.log.debug1(self) { "defining pattern => #{name}" }
131
+ define_pattern_internal(name, &block)
132
+ end
133
+
134
+ def weave(name, pattern_slugs)
135
+ Loom.log.debug1(self) { "defining weave => #{name}" }
136
+ @weave_slugs ||= {}
137
+ @weave_slugs[name.to_sym] = pattern_slugs.map { |s| s.to_s }
138
+
139
+ unless @next_description
140
+ @next_description = "Weave runs patterns: %s" % pattern_slugs.join(", ")
141
+ end
142
+
143
+ define_pattern_internal(name) { |_, _| true }
144
+ end
145
+
146
+ def define_pattern_internal(name, &block)
124
147
  @pattern_methods ||= []
125
148
  @pattern_method_map ||= {}
126
149
  @pattern_descriptions ||= {}
@@ -148,6 +171,14 @@ module Loom::Pattern
148
171
  hook :after, &block
149
172
  end
150
173
 
174
+ def weave_slugs
175
+ @weave_slugs || {}
176
+ end
177
+
178
+ def is_weave?(name)
179
+ !!weave_slugs[name]
180
+ end
181
+
151
182
  def pattern_methods
152
183
  @pattern_methods || []
153
184
  end
@@ -0,0 +1,16 @@
1
+ module Loom::Pattern
2
+ class ExpandingReference
3
+
4
+ attr_reader :slug, :reference_slugs, :source_file, :desc
5
+
6
+ def initialize(slug, reference_slugs, source_file, description)
7
+ @slug = slug
8
+ @reference_slugs = reference_slugs
9
+ @desc = description
10
+ end
11
+
12
+ def is_expanding?
13
+ true
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,7 @@
1
1
  module Loom::Pattern
2
2
 
3
3
  SiteFileNotFound = Class.new Loom::LoomError
4
+ RecursiveExpansionError = Class.new Loom::LoomError
4
5
 
5
6
  class Loader
6
7
  class << self
@@ -24,7 +25,8 @@ module Loom::Pattern
24
25
  if slugs.nil?
25
26
  @reference_set.pattern_refs
26
27
  else
27
- slugs.map { |slug| get_pattern_ref(slug) }
28
+ refs = slugs.map { |slug| get_pattern_ref(slug) }
29
+ expand_refs(refs)
28
30
  end
29
31
  end
30
32
 
@@ -44,5 +46,24 @@ module Loom::Pattern
44
46
  def load_pattern_file(f)
45
47
  @reference_set.merge! ReferenceSet.load_from_file(f)
46
48
  end
49
+
50
+ def expand_refs(refs)
51
+ refs.flat_map do |ref|
52
+ if ref.is_expanding?
53
+ expanded_refs = ref.reference_slugs.map { |s| get_pattern_ref(s) }
54
+ expanded_refs.each do |exp_ref|
55
+ if exp_ref.is_expanding?
56
+ Loom.log.error "error expanding pattern[#{exp_ref.slug}] in weave[#{ref.slug}], i.e. only patterns are allowed in weaves"
57
+ raise RecursiveExpansionError, ref.slug
58
+ end
59
+ end
60
+ Loom.log.info(
61
+ "expanded pattern #{ref.slug} to patterns: #{expanded_refs.map(&:slug).join(",")}")
62
+ expanded_refs
63
+ else
64
+ ref
65
+ end
66
+ end
67
+ end
47
68
  end
48
69
  end
@@ -11,6 +11,10 @@ module Loom::Pattern
11
11
  @desc = description
12
12
  end
13
13
 
14
+ def is_expanding?
15
+ false
16
+ end
17
+
14
18
  def call(shell_api, host_fact_set)
15
19
  run_context = RunContext.new @unbound_method, @definition_ctx
16
20
 
@@ -1,3 +1,8 @@
1
+ # THERE BE DRAGONS HERE
2
+ # TODO: add documentation re: how the .loom file is parsed (exec'd) and turned
3
+ # into a reference set. There's also a lot of dark magic w/ generating
4
+ # stacktraces to get the correct .loom file line (but I forget if that's done
5
+ # here or in pattern/reference.rb maybe?)
1
6
  module Loom::Pattern
2
7
 
3
8
  DuplicatePatternRef = Class.new Loom::LoomError
@@ -54,6 +59,8 @@ module Loom::Pattern
54
59
  def create(ruby_code, source)
55
60
  shell_module = Module.new
56
61
  shell_module.include Loom::Pattern
62
+ # TODO: I think this is my black magic for capturing stacktrace
63
+ # info... I forget the details. Add documentation.
57
64
  shell_module.module_eval ruby_code, source, 1
58
65
  shell_module.namespace ""
59
66
 
@@ -81,18 +88,35 @@ module Loom::Pattern
81
88
  def refs_for_mod_spec(mod_spec)
82
89
  mod = mod_spec[:module]
83
90
  context = context_for_mod_spec mod_spec
84
- source = @source
85
91
 
86
92
  mod_spec[:pattern_methods].map do |m|
87
- method = mod.pattern_method m
88
- desc = mod.pattern_description m
89
93
  slug = compute_slug mod_spec[:namespace_list], m
90
94
 
91
- Loom.log.warn "no descripiton for pattern => #{slug}" unless desc
92
- Reference.new slug, method, source, context, desc
95
+ if mod.is_weave?(m)
96
+ Loom.log.debug2(self) { "adding ExpandingReference for weave: #{slug}" }
97
+ build_expanding_reference(m, slug, mod)
98
+ else
99
+ Loom.log.debug2(self) { "adding Reference for pattern: #{slug}" }
100
+ build_pattern_reference(m, slug, context, mod)
101
+ end
93
102
  end
94
103
  end
95
104
 
105
+ def build_expanding_reference(weave_name, slug, mod)
106
+ desc = mod.pattern_description weave_name
107
+ Loom.log.warn "no descripiton for weave => #{slug}" unless desc
108
+
109
+ ExpandingReference.new slug, mod.weave_slugs[weave_name], @source, desc
110
+ end
111
+
112
+ def build_pattern_reference(pattern_name, slug, context, mod)
113
+ method = mod.pattern_method pattern_name
114
+ desc = mod.pattern_description pattern_name
115
+ Loom.log.warn "no descripiton for pattern => #{slug}" unless desc
116
+
117
+ Reference.new slug, method, @source, context, desc
118
+ end
119
+
96
120
  def context_for_mod_spec(mod_spec)
97
121
  parents = mod_spec[:parent_modules].find_all do |mod|
98
122
  is_pattern_module mod
@@ -128,7 +128,7 @@ module Loom
128
128
  end
129
129
 
130
130
  Loom.log.debug "collecting facts for => #{pattern_description}"
131
- # Collect facts for each pattern run on each host, this way if one
131
+ # Collects facts for each pattern run on each host, this way if one
132
132
  # pattern run updates would be facts, the next pattern will see the
133
133
  # new fact.
134
134
  fact_shell = Loom::Shell.create @mod_loader, sshkit_backend, dry_run
@@ -136,10 +136,8 @@ module Loom
136
136
  .merge @other_facts
137
137
 
138
138
  Loom.log.info "running pattern => #{pattern_description}"
139
- # Each pattern execution needs its own shell and mod loader to make
140
- # sure context is reported correctly (this is probably a hack, there
141
- # should just be a way to clear/ignore state from certain commands -
142
- # like the fact_finding ones above).
139
+ # Creates a new shell for executing the pattern, so as not to be
140
+ # tainted by the fact finding shell above.
143
141
  pattern_shell = Loom::Shell.create @mod_loader, sshkit_backend, dry_run
144
142
 
145
143
  Loom.log.warn "dry run only => #{pattern_description}" if dry_run
@@ -165,9 +163,11 @@ module Loom
165
163
  result_reporter = Loom::Pattern::ResultReporter.new(
166
164
  @loom_config, pattern_ref.slug, hostname, shell_session)
167
165
 
168
- # TODO: This is a crappy mechanism for tracking errors (hency my crappy error reporting :( ),
169
- # there should be an exception thrown inside of Shell when a command fails and pattern
170
- # execution should stop. All errors should come from exceptions.
166
+ # TODO: This is a crappy mechanism for tracking errors - hency my crappy
167
+ # error reporting :( - there should be an exception thrown inside of Shell
168
+ # when a command fails and pattern execution should stop. All errors
169
+ # should come from exceptions. This needs to be thought about wrt to the
170
+ # defined `failure_strategy`
171
171
  run_failure = []
172
172
  begin
173
173
  pattern_ref.call(shell.shell_api, fact_set)
@@ -175,8 +175,8 @@ module Loom
175
175
  Loom.log.debug e.backtrace.join "\n\t"
176
176
  run_failure << e
177
177
  ensure
178
- # TODO[P0]: this prints out [Result: OK] even if an exception is raised... this is really
179
- # annoying.
178
+ # TODO[P0]: this prints out [Result: OK] even if an exception is
179
+ # raised... this is really annoying.
180
180
  result_reporter.write_report
181
181
 
182
182
  # TODO: this is not the correct error condition.
@@ -198,10 +198,10 @@ module Loom
198
198
  Loom.log.warn "disabling host per :run_failure_strategy => #{failure_strategy}"
199
199
  @inventory_list.disable hostname
200
200
  when :fail_fast
201
- Loom.log.error "erroring out of failed scenario per :run_failure_strategy"
201
+ Loom.log.error "erroring out of failed pattern per :run_failure_strategy"
202
202
  raise FailFastExecutionError, failure_summary
203
203
  when :cowboy
204
- Loom.log.warn "continuing on past failed scenario per :run_failure_strategy"
204
+ Loom.log.warn "continuing on past failed pattern per :run_failure_strategy"
205
205
  else
206
206
  raise ConfigError, "unknown failure_strategy: #{failure_stratgy}"
207
207
  end
@@ -1,3 +1,3 @@
1
1
  module Loom
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loom-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erick Johnson
@@ -228,6 +228,7 @@ files:
228
228
  - lib/loom/pattern/all.rb
229
229
  - lib/loom/pattern/definition_context.rb
230
230
  - lib/loom/pattern/dsl.rb
231
+ - lib/loom/pattern/expanding_reference.rb
231
232
  - lib/loom/pattern/hook.rb
232
233
  - lib/loom/pattern/loader.rb
233
234
  - lib/loom/pattern/reference.rb