loom-core 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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