opswalrus 1.0.47 → 1.0.49

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: 9d9a70d6f9200acd372ab13f63628a04cffd1cd4509e3ac24af448b179a6f192
4
- data.tar.gz: 750f7704aa249784a9261b2910a1c8b3786ba03b32e52fe16d07c8de82cced06
3
+ metadata.gz: 90e3b3e2c7e0255ef069e30d31e2125c5bf6fd9c22a15e4aa2057f5265aa6873
4
+ data.tar.gz: 58346bbbcfe19a98add4a83b8936f75c911155f872cf35ecaf56ce32679c1123
5
5
  SHA512:
6
- metadata.gz: 4774c0ec9370ecb0e7251131bcc8e6a192c6009e7d7200fbd93dacdddbcec68cf3b2042b086cb8be1f7310721a2303b9f3fd04e40a52c3aecc557ff711b060b6
7
- data.tar.gz: 8a7c15b5c16182b806efc85e8e307d9d98f29715aa2e84b4067413b90484c9f19fc94b7e9c294845f48623c2cd776bc8d284ee2bde6e74d76af1d6f38d925345
6
+ metadata.gz: bde3099dff40f9f00add304bac22a5cf62521a68ed3c9481d7de9ae28f3d520c4457097c3be60fbb569e6c32de4fdc101e620fd5a2ad832d335b638245dcd93e
7
+ data.tar.gz: a1b4a440fd1d9512efe0cdef6110f3849afab3ad3253140dfa253bb30d7fac606a0de6b814f3611e0c063366a9478a2b4fc3ae5e3c962b02d6c76f2dd815dbb2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.47)
4
+ opswalrus (1.0.49)
5
5
  bcrypt_pbkdf (~> 1.1)
6
6
  binding_of_caller (~> 1.0)
7
7
  citrus (~> 3.0)
data/build.ops CHANGED
@@ -30,7 +30,9 @@ end
30
30
  TEMPLATE
31
31
 
32
32
  puts "Write version.rb for version #{version}"
33
- core.template.write(path: "./lib/opswalrus/version.rb", template: template, variables: {version: version})
33
+ core.template.write template: template,
34
+ variables: {version: version},
35
+ to: "./lib/opswalrus/version.rb"
34
36
 
35
37
  sh("Build gem") { 'gem build opswalrus.gemspec' }
36
38
 
data/lib/opswalrus/app.rb CHANGED
@@ -249,6 +249,9 @@ module OpsWalrus
249
249
  puts JSON.pretty_generate(result.value)
250
250
 
251
251
  exit_status
252
+ rescue Error => e
253
+ puts "Error: #{e.message}"
254
+ 1
252
255
  ensure
253
256
  FileUtils.remove_entry(tmp_bundle_root_dir) if tmp_bundle_root_dir
254
257
  end
@@ -1,15 +1,5 @@
1
1
  # ssh_noprep in: :sequence do
2
2
  ssh_noprep do
3
3
  puts "Bootstrapping #{to_s} (alias=#{self.alias})"
4
- stdout, stderr, exit_status = _bootstrap_host()
5
- if exit_status == 0
6
- puts "Success - #{to_s} (alias=#{self.alias})"
7
- else
8
- stdout_report = stdout.lines.last(3).map {|line| " #{line}" }.join()
9
- stderr_report = stderr.lines.last(3).map {|line| " #{line}" }.join()
10
- report = "Failure - #{to_s} (alias=#{self.alias})"
11
- report << "\n stdout:\n#{stdout_report}" unless stdout_report.empty?
12
- report << "\n stderr:\n#{stderr_report}" unless stderr_report.empty?
13
- puts report
14
- end
4
+ _bootstrap_host(true)
15
5
  end
@@ -82,7 +82,7 @@ module OpsWalrus
82
82
  end
83
83
 
84
84
  # returns [stdout, stderr, exit_status]
85
- def _bootstrap_host
85
+ def _bootstrap_host(print_report = true)
86
86
  # copy over bootstrap shell script
87
87
  # io = StringIO.new(bootstrap_shell_script)
88
88
  io = File.open(__FILE__.to_pathname.dirname.join("bootstrap.sh"))
@@ -91,7 +91,23 @@ module OpsWalrus
91
91
  raise Error, "Unable to upload bootstrap shell script to remote host #{to_s} (alias=#{self.alias})" unless upload_success
92
92
  @_host.execute(:chmod, "755", "tmpopsbootstrap.sh")
93
93
  sshkit_cmd = @_host.execute_cmd(:sh, "tmpopsbootstrap.sh")
94
- [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
94
+
95
+ stdout, stderr, exit_status = [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
96
+
97
+ if print_report
98
+ if exit_status == 0
99
+ puts "Bootstrap success - #{to_s} (alias=#{self.alias})"
100
+ else
101
+ stdout_report = stdout.lines.last(3).map {|line| " #{line}" }.join()
102
+ stderr_report = stderr.lines.last(3).map {|line| " #{line}" }.join()
103
+ report = "Bootstrap failure - #{to_s} (alias=#{self.alias})"
104
+ report << "\n stdout:\n#{stdout_report}" unless stdout_report.empty?
105
+ report << "\n stderr:\n#{stderr_report}" unless stderr_report.empty?
106
+ puts report
107
+ end
108
+ end
109
+
110
+ [stdout, stderr, exit_status]
95
111
  ensure
96
112
  @_host.execute(:rm, "-f", "tmpopsbootstrap.sh") rescue nil
97
113
  end
@@ -264,6 +280,14 @@ module OpsWalrus
264
280
  puts Style.green(msg.mustache(2)) # we use two here, because one stack frame accounts for the call from the ops script into HostProxy#desc
265
281
  end
266
282
 
283
+ def warn(msg)
284
+ puts Style.yellow(msg.mustache(2)) # we use two here, because one stack frame accounts for the call from the ops script into HostProxy#desc
285
+ end
286
+
287
+ def debug(msg)
288
+ puts msg.mustache(2) if App.instance.debug? || App.instance.trace? # we use two here, because one stack frame accounts for the call from the ops script into HostProxy#desc
289
+ end
290
+
267
291
  def env(*args, **kwargs)
268
292
  @ops_file_script.env(*args, **kwargs)
269
293
  end
@@ -419,7 +443,7 @@ module OpsWalrus
419
443
 
420
444
  def clear_ssh_session
421
445
  @runtime_env = nil
422
- ops_file_script = nil
446
+ @ops_file_script = nil
423
447
  @sshkit_backend = nil
424
448
  @tmp_bundle_root_dir = nil
425
449
  @tmp_ssh_key_files.each {|tmpfile| tmpfile.close() rescue nil; File.unlink(tmpfile) rescue nil }
@@ -99,14 +99,14 @@ module OpsWalrus
99
99
  App.instance.error "[!] Command failed: #{e.message}"
100
100
  rescue Error => e
101
101
  App.instance.error "Error: Ops script crashed."
102
- App.instance.error e
103
- # App.instance.error e.backtrace.take(5).join("\n")
102
+ App.instance.error e.message
103
+ App.instance.error e.backtrace.take(10).join("\n")
104
104
  Invocation::Error.new(e)
105
105
  rescue => e
106
106
  App.instance.error "Unhandled Error: Ops script crashed."
107
107
  App.instance.error e.class
108
- App.instance.error e
109
- # App.instance.error e.backtrace.take(10).join("\n")
108
+ App.instance.error e.message
109
+ App.instance.error e.backtrace.take(10).join("\n")
110
110
  Invocation::Error.new(e)
111
111
  end
112
112
 
@@ -139,11 +139,12 @@ module OpsWalrus
139
139
  def _invoke(runtime_env, hashlike_params)
140
140
  @runtime_env = runtime_env
141
141
  @params = InvocationParams.new(hashlike_params)
142
+ @runtime_ops_file_path = __FILE__
142
143
  #{ruby_script}
143
144
  end
144
145
  INVOKE_METHOD
145
146
 
146
- invoke_method_line_count_prior_to_ruby_script_from_ops_file = 3
147
+ invoke_method_line_count_prior_to_ruby_script_from_ops_file = 4
147
148
  klass.module_eval(invoke_method_definition, ops_file.ops_file_path.to_s, ops_file.script_line_offset - invoke_method_line_count_prior_to_ruby_script_from_ops_file)
148
149
 
149
150
  klass
@@ -157,8 +158,9 @@ module OpsWalrus
157
158
  def initialize(ops_file, ruby_script)
158
159
  @ops_file = ops_file
159
160
  @script = ruby_script
160
- @runtime_env = nil # this is set at the very first line of #_invoke
161
- @params = nil # this is set at the very first line of #_invoke
161
+ @runtime_env = nil # this is set at the very first line of #_invoke
162
+ @params = nil # this is set at the very first line of #_invoke
163
+ @runtime_ops_file_path = nil # this is set at the very first line of #_invoke
162
164
  end
163
165
 
164
166
  def backend
@@ -183,6 +185,10 @@ module OpsWalrus
183
185
  end
184
186
  end
185
187
 
188
+ def inspect
189
+ "OpsFileScript[#{ops_file.ops_file_path}]"
190
+ end
191
+
186
192
  def to_s
187
193
  @script
188
194
  end
@@ -120,8 +120,12 @@ module OpsWalrus
120
120
  host.set_ops_file_script(ops_file_script)
121
121
  host.set_ssh_session_connection(self) # self is an instance of one of the subclasses of SSHKit::Backend::Abstract, e.g. SSHKit::Backend::Netssh
122
122
 
123
- host._bootstrap_host
124
- retval = host._zip_copy_and_run_ops_bundle(local_host, block)
123
+ stdout, stderr, exit_status = host._bootstrap_host(false)
124
+ retval = if exit_status == 0
125
+ host._zip_copy_and_run_ops_bundle(local_host, block)
126
+ else
127
+ puts "Failed to bootstrap #{host}. Unable to run operation."
128
+ end
125
129
 
126
130
  retval
127
131
  rescue SSHKit::Command::Failed => e
@@ -153,6 +157,10 @@ module OpsWalrus
153
157
  end
154
158
  end
155
159
 
160
+ def current_dir
161
+ File.dirname(File.realpath(@runtime_ops_file_path)).to_pathname
162
+ end
163
+
156
164
  def inventory(*args, **kwargs)
157
165
  tags = args.map(&:to_s)
158
166
 
@@ -194,6 +202,14 @@ module OpsWalrus
194
202
  puts Style.green(msg.mustache(1))
195
203
  end
196
204
 
205
+ def warn(msg)
206
+ puts Style.yellow(msg.mustache(1))
207
+ end
208
+
209
+ def debug(msg)
210
+ puts msg.mustache(1) if App.instance.debug? || App.instance.trace?
211
+ end
212
+
197
213
  def env(*keys)
198
214
  keys = keys.map(&:to_s)
199
215
  if keys.empty?
@@ -245,10 +261,26 @@ module OpsWalrus
245
261
  end
246
262
  #cmd = Shellwords.escape(cmd)
247
263
 
264
+ report_on(@runtime_env.local_hostname, description, cmd, log_level: log_level) do
265
+ if App.instance.dry_run?
266
+ ["", "", 0]
267
+ else
268
+ sshkit_cmd = @runtime_env.handle_input(input, inherit_existing_mappings: true) do |interaction_handler|
269
+ # puts "self=#{self.class.superclass}"
270
+ # self is an instance of one of the dynamically defined subclasses of OpsFileScript
271
+ App.instance.debug("OpsFileScriptDSL#shell! cmd=#{cmd} with input mappings #{interaction_handler.input_mappings.inspect} given input: #{input.inspect})")
272
+ backend.execute_cmd(cmd, interaction_handler: interaction_handler)
273
+ end
274
+ [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
275
+ end
276
+ end
277
+ end
278
+
279
+ def report_on(hostname, description = nil, cmd, log_level: nil)
248
280
  cmd_id = Random.uuid.split('-').first
249
281
 
250
282
  output_block = StringIO.open do |io|
251
- io.print Style.blue(@runtime_env.local_hostname)
283
+ io.print Style.blue(hostname)
252
284
  io.print " | #{Style.magenta(description)}" if description
253
285
  io.puts
254
286
  io.print Style.yellow(cmd_id)
@@ -258,20 +290,8 @@ module OpsWalrus
258
290
  end
259
291
  puts output_block
260
292
 
261
- return unless cmd && !cmd.strip.empty?
262
-
263
293
  t1 = Time.now
264
- out, err, exit_status = if App.instance.dry_run?
265
- ["", "", 0]
266
- else
267
- sshkit_cmd = @runtime_env.handle_input(input, inherit_existing_mappings: true) do |interaction_handler|
268
- # self is a Module instance that is serving as the evaluation context in an instance of a subclass of an Invocation; see Invocation#evaluate
269
- # backend.execute_cmd(cmd, interaction_handler: interaction_handler, verbosity: SSHKit.config.output_verbosity)
270
- App.instance.debug("OpsFileScriptDSL#shell! cmd=#{cmd} with input mappings #{interaction_handler.input_mappings.inspect} given input: #{input.inspect})")
271
- backend.execute_cmd(cmd, interaction_handler: interaction_handler)
272
- end
273
- [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
274
- end
294
+ out, err, exit_status = yield
275
295
  t2 = Time.now
276
296
  seconds = t2 - t1
277
297
 
@@ -20,3 +20,72 @@ class Pathname
20
20
  self
21
21
  end
22
22
  end
23
+
24
+
25
+ class String
26
+ def boolean!(default: false)
27
+ boolean_str = strip.downcase
28
+ case boolean_str
29
+ when "true"
30
+ true
31
+ when "false"
32
+ false
33
+ else
34
+ default
35
+ end
36
+ end
37
+
38
+ def string!(default: "")
39
+ self
40
+ end
41
+ end
42
+
43
+ class Integer
44
+ def boolean!(default: false)
45
+ true
46
+ end
47
+
48
+ def string!(default: "")
49
+ to_s
50
+ end
51
+ end
52
+
53
+ class Float
54
+ def boolean!(default: false)
55
+ true
56
+ end
57
+
58
+ def string!(default: "")
59
+ to_s
60
+ end
61
+ end
62
+
63
+ class NilClass
64
+ def boolean!(default: false)
65
+ default
66
+ end
67
+
68
+ def string!(default: "")
69
+ default
70
+ end
71
+ end
72
+
73
+ class TrueClass
74
+ def boolean!(default: false)
75
+ self
76
+ end
77
+
78
+ def string!(default: "")
79
+ to_s
80
+ end
81
+ end
82
+
83
+ class FalseClass
84
+ def boolean!(default: false)
85
+ self
86
+ end
87
+
88
+ def string!(default: "")
89
+ to_s
90
+ end
91
+ end
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.47"
2
+ VERSION = "1.0.49"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opswalrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.47
4
+ version: 1.0.49
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Ellis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-13 00:00:00.000000000 Z
11
+ date: 2023-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: binding_of_caller