opswalrus 1.0.52 → 1.0.53

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: b1ce678751d6d62f4a9b5e40eb6127c22e2e664c6641023ce8df4135609fb73e
4
- data.tar.gz: a2747abc2711e77a47371f7c16d1b5104d70b10419b09cd3e992e892cea2d6ca
3
+ metadata.gz: 007f1ac465143fdd629539509b94a8bf7230b034817526d1265768f97eae0786
4
+ data.tar.gz: 9d0cc607ce7c9fcd06d9e402254b3eb5a75a68687a1ee485aa915b3cd488e2b6
5
5
  SHA512:
6
- metadata.gz: 5ec4e2b6a547e394b0290a47dafa7cc13960a9c21cef7e1a7edc4d20900cd304a1e0c828025df68f8e7e2e6ce22e3f48882fe44efcaaf1a25e3c74d357981071
7
- data.tar.gz: 386afc9a49856131615ff5c5e0c54a1934bf8458d3a77f7f2c6e1da6479343c54a0be8436f8a08beec4e89d6f1b9019e463bc96a5c169f639a7061838f8f240f
6
+ metadata.gz: 83b67721de074efa3ad368ed21ec469d40928351c4ccc6f32d530e3bbda2cdd81b62f2b72692a4796b74d1efb7bbbfa31721db0eefb93864069dc277f8aa66fe
7
+ data.tar.gz: b54d628df099de1f4c2eea591b86449b5fd254d495ccae38f89dd95f5d1137171aaf9e6c1bd2023613f1c33561b5e49bd12d5696d6bc197bc065ead0a79aed1d
data/Gemfile CHANGED
@@ -7,3 +7,5 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
9
  gem "rspec", "~> 3.0"
10
+
11
+ gem 'solargraph', group: :development
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.52)
4
+ opswalrus (1.0.53)
5
+ activesupport (~> 7.0)
5
6
  bcrypt_pbkdf (~> 1.1)
6
7
  binding_of_caller (~> 1.0)
7
8
  citrus (~> 3.0)
@@ -17,28 +18,61 @@ PATH
17
18
  GEM
18
19
  remote: https://rubygems.org/
19
20
  specs:
21
+ activesupport (7.0.8)
22
+ concurrent-ruby (~> 1.0, >= 1.0.2)
23
+ i18n (>= 1.6, < 2)
24
+ minitest (>= 5.1)
25
+ tzinfo (~> 2.0)
20
26
  addressable (2.8.5)
21
27
  public_suffix (>= 2.0.2, < 6.0)
28
+ ast (2.4.2)
29
+ backport (1.2.0)
30
+ base64 (0.1.1)
22
31
  bcrypt_pbkdf (1.1.0)
32
+ benchmark (0.2.1)
23
33
  binding_of_caller (1.0.0)
24
34
  debug_inspector (>= 0.0.1)
25
35
  citrus (3.0.2)
26
36
  concurrent-ruby (1.2.2)
27
37
  debug_inspector (1.1.0)
28
38
  diff-lcs (1.5.0)
39
+ e2mmap (0.1.0)
29
40
  ed25519 (1.3.0)
30
41
  git (1.18.0)
31
42
  addressable (~> 2.8)
32
43
  rchardet (~> 1.8)
33
44
  gli (2.21.1)
45
+ i18n (1.14.1)
46
+ concurrent-ruby (~> 1.0)
47
+ jaro_winkler (1.5.6)
48
+ json (2.6.3)
49
+ kramdown (2.4.0)
50
+ rexml
51
+ kramdown-parser-gfm (1.1.0)
52
+ kramdown (~> 2.0)
53
+ language_server-protocol (3.17.0.3)
54
+ minitest (5.20.0)
34
55
  net-scp (4.0.0)
35
56
  net-ssh (>= 2.6.5, < 8.0.0)
36
57
  net-ssh (7.2.0)
58
+ nokogiri (1.15.4-x86_64-linux)
59
+ racc (~> 1.4)
60
+ parallel (1.23.0)
61
+ parser (3.2.2.3)
62
+ ast (~> 2.4.1)
63
+ racc
37
64
  pastel (0.8.0)
38
65
  tty-color (~> 0.5)
39
66
  public_suffix (5.0.3)
67
+ racc (1.7.1)
68
+ rainbow (3.1.1)
40
69
  rake (13.0.6)
70
+ rbs (2.8.4)
41
71
  rchardet (1.8.0)
72
+ regexp_parser (2.8.1)
73
+ reverse_markdown (2.1.1)
74
+ nokogiri
75
+ rexml (3.2.6)
42
76
  rspec (3.12.0)
43
77
  rspec-core (~> 3.12.0)
44
78
  rspec-expectations (~> 3.12.0)
@@ -52,12 +86,45 @@ GEM
52
86
  diff-lcs (>= 1.2.0, < 2.0)
53
87
  rspec-support (~> 3.12.0)
54
88
  rspec-support (3.12.1)
89
+ rubocop (1.56.3)
90
+ base64 (~> 0.1.1)
91
+ json (~> 2.3)
92
+ language_server-protocol (>= 3.17.0)
93
+ parallel (~> 1.10)
94
+ parser (>= 3.2.2.3)
95
+ rainbow (>= 2.2.2, < 4.0)
96
+ regexp_parser (>= 1.8, < 3.0)
97
+ rexml (>= 3.2.5, < 4.0)
98
+ rubocop-ast (>= 1.28.1, < 2.0)
99
+ ruby-progressbar (~> 1.7)
100
+ unicode-display_width (>= 2.4.0, < 3.0)
101
+ rubocop-ast (1.29.0)
102
+ parser (>= 3.2.1.0)
103
+ ruby-progressbar (1.13.0)
55
104
  rubyzip (2.3.2)
56
105
  semantic_logger (4.14.0)
57
106
  concurrent-ruby (~> 1.0)
107
+ solargraph (0.49.0)
108
+ backport (~> 1.2)
109
+ benchmark
110
+ bundler (~> 2.0)
111
+ diff-lcs (~> 1.4)
112
+ e2mmap
113
+ jaro_winkler (~> 1.5)
114
+ kramdown (~> 2.3)
115
+ kramdown-parser-gfm (~> 1.1)
116
+ parser (~> 3.0)
117
+ rbs (~> 2.0)
118
+ reverse_markdown (~> 2.0)
119
+ rubocop (~> 1.38)
120
+ thor (~> 1.0)
121
+ tilt (~> 2.0)
122
+ yard (~> 0.9, >= 0.9.24)
58
123
  sshkit (1.21.5)
59
124
  net-scp (>= 1.1.2)
60
125
  net-ssh (>= 2.8.0)
126
+ thor (1.2.2)
127
+ tilt (2.3.0)
61
128
  tty-color (0.6.0)
62
129
  tty-cursor (0.7.1)
63
130
  tty-editor (0.7.0)
@@ -70,7 +137,11 @@ GEM
70
137
  tty-screen (~> 0.8)
71
138
  wisper (~> 2.0)
72
139
  tty-screen (0.8.1)
140
+ tzinfo (2.0.6)
141
+ concurrent-ruby (~> 1.0)
142
+ unicode-display_width (2.4.2)
73
143
  wisper (2.0.1)
144
+ yard (0.9.34)
74
145
 
75
146
  PLATFORMS
76
147
  x86_64-linux
@@ -79,6 +150,7 @@ DEPENDENCIES
79
150
  opswalrus!
80
151
  rake (~> 13.0)
81
152
  rspec (~> 3.0)
153
+ solargraph
82
154
 
83
155
  BUNDLED WITH
84
156
  2.4.10
@@ -0,0 +1,12 @@
1
+ params:
2
+ ops_file: OpsFile
3
+ operation_kv_args: array string
4
+ ...
5
+ ssh in: :sequence do
6
+ # ssh_noprep do
7
+ puts params.stringify_keys!
8
+ desc "Running `#{params.ops_file.ops_file_path} #{params.operation_kv_args.join(' ')}` on #{to_s} (alias=#{self.alias})"
9
+ # run_ops(ops_command, ops_command_options = nil, command_arguments, in_bundle_root_dir: true, ops_prompt_for_sudo_password: false)
10
+ puts self.inspect
11
+ self._invoke_remote(params.ops_file, *params.operation_kv_args)
12
+ end
data/lib/opswalrus/app.rb CHANGED
@@ -38,11 +38,11 @@ module OpsWalrus
38
38
  attr_reader :identity_file_paths
39
39
 
40
40
  def initialize(pwd = Dir.pwd)
41
- SemanticLogger.default_level = :info
41
+ SemanticLogger.default_level = :warn
42
42
  # SemanticLogger.add_appender(file_name: 'development.log', formatter: :color) # Log to a file, and use the colorized formatter
43
43
  SemanticLogger.add_appender(io: $stdout, formatter: :color) # Log errors and above to standard error:
44
44
  @logger = SemanticLogger[OpsWalrus] # Logger.new($stdout, level: Logger::INFO)
45
- @logger.level = :info # , :trace or 'trace'
45
+ @logger.level = :warn # :trace or 'trace'
46
46
 
47
47
  # @logger.warn Style.yellow("warn"), foo: "bar", baz: {qux: "quux"}
48
48
  # @logger.info Style.yellow("info"), foo: "bar", baz: {qux: "quux"}
@@ -216,18 +216,22 @@ module OpsWalrus
216
216
  end
217
217
 
218
218
  def bootstrap()
219
- set_pwd(__FILE__.to_pathname.dirname)
220
- bootstrap_ops_file = OpsFile.new(self, __FILE__.to_pathname.dirname.join("_bootstrap.ops"))
221
- op = OperationRunner.new(self, bootstrap_ops_file)
222
- op.run([], params_json_hash: @params)
219
+ run_internal("_bootstrap.ops")
223
220
  end
224
221
 
225
222
  def shell(command)
223
+ run_internal("_shell.ops", {"command" => command})
224
+ end
225
+
226
+ def reboot()
227
+ run_internal("_reboot.ops")
228
+ end
229
+
230
+ def run_internal(ops_file_name, params = @params)
226
231
  set_pwd(__FILE__.to_pathname.dirname)
227
- shell_ops_file = OpsFile.new(self, __FILE__.to_pathname.dirname.join("_shell.ops"))
228
- op = OperationRunner.new(self, shell_ops_file)
229
- puts "running #{command}"
230
- result = op.run([], params_json_hash: {"command" => command})
232
+ internal_ops_file = OpsFile.new(self, __FILE__.to_pathname.dirname.join(ops_file_name))
233
+ op = OperationRunner.new(self, internal_ops_file)
234
+ result = op.run([], params_json_hash: params)
231
235
  puts "result class=#{result.class}"
232
236
  exit_status = result.exit_status
233
237
  stdout = JSON.pretty_generate(result.value)
@@ -243,27 +247,45 @@ module OpsWalrus
243
247
  1
244
248
  end
245
249
 
246
- def reboot()
247
- set_pwd(__FILE__.to_pathname.dirname)
248
- shell_ops_file = OpsFile.new(self, __FILE__.to_pathname.dirname.join("_reboot.ops"))
249
- op = OperationRunner.new(self, shell_ops_file)
250
- result = op.run([], params_json_hash: @params)
251
- puts "result class=#{result.class}"
250
+ # package_operation_and_args is of the form ["github.com/davidkellis/my-package/sub-package1", "operation1", "arg1:val1", "arg2:val2", "arg3:val3"]
251
+ # if the first argument is the path to a .ops file, then treat it as a local path, and add the containing package
252
+ # to the load path
253
+ # otherwise, copy the
254
+ # returns the exit status code that the script should terminate with
255
+ def run_remote(package_operation_and_args, update_bundle: false)
256
+ return 0 if package_operation_and_args.empty?
257
+
258
+ ops_file_path, operation_kv_args, tmp_bundle_root_dir = get_entry_point_ops_file_and_args(package_operation_and_args)
259
+
260
+ ops_file = load_entry_point_ops_file(ops_file_path, tmp_bundle_root_dir)
261
+
262
+ bundler.update if update_bundle
263
+
264
+ debug "Running: #{ops_file.ops_file_path}"
265
+
266
+ internal_ops_file = OpsFile.new(self, __FILE__.to_pathname.dirname.join("_run_remote.ops"))
267
+
268
+ op = OperationRunner.new(self, internal_ops_file)
269
+ result = op.run([], params_json_hash: {ops_file: ops_file, operation_kv_args: operation_kv_args})
252
270
  exit_status = result.exit_status
253
- stdout = JSON.pretty_generate(result.value)
254
- output = if exit_status == 0
255
- Style.green(stdout)
256
- else
257
- Style.red(stdout)
258
- end
259
- puts output
271
+
272
+ debug "Op exit_status"
273
+ debug exit_status
274
+
275
+ debug "Op output"
276
+ debug JSON.pretty_generate(result.value)
277
+
278
+ puts JSON.pretty_generate(result.value)
279
+
260
280
  exit_status
261
281
  rescue Error => e
262
282
  puts "Error: #{e.message}"
263
283
  1
284
+ ensure
285
+ FileUtils.remove_entry(tmp_bundle_root_dir) if tmp_bundle_root_dir
264
286
  end
265
287
 
266
- # args is of the form ["github.com/davidkellis/my-package/sub-package1", "operation1", "arg1:val1", "arg2:val2", "arg3:val3"]
288
+ # package_operation_and_args is of the form ["github.com/davidkellis/my-package/sub-package1", "operation1", "arg1:val1", "arg2:val2", "arg3:val3"]
267
289
  # if the first argument is the path to a .ops file, then treat it as a local path, and add the containing package
268
290
  # to the load path
269
291
  # otherwise, copy the
data/lib/opswalrus/cli.rb CHANGED
@@ -30,13 +30,11 @@ module OpsWalrus
30
30
 
31
31
  program_desc 'ops is an operation runner'
32
32
 
33
- switch [:v, :verbose], desc: "Verbose output"
34
- switch :debug, desc: "Debug output"
35
- switch :trace, desc: "Trace output"
33
+ switch :loud, desc: "Verbose output"
34
+ switch :louder, desc: "Debug output"
35
+ switch :loudest, desc: "Trace output"
36
36
 
37
- switch :noop, desc: "Perform a dry run"
38
- switch :dryrun, desc: "Perform a dry run"
39
- switch :dry_run, desc: "Perform a dry run"
37
+ switch :dry, desc: "Perform a dry run"
40
38
 
41
39
  flag [:h, :hosts], multiple: true, desc: "Specify the hosts.yaml file"
42
40
  flag [:t, :tags], multiple: true, desc: "Specify a set of tags to filter the hosts by"
@@ -61,7 +59,7 @@ module OpsWalrus
61
59
  hosts = global_options[:hosts]
62
60
  tags = global_options[:tags]
63
61
 
64
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
62
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
65
63
 
66
64
  $app.report_inventory(hosts, tags: tags)
67
65
  end
@@ -123,12 +121,10 @@ module OpsWalrus
123
121
  long_desc 'Bootstrap a set of hotss to run opswalrus: install dependencies, ruby, opswalrus gem'
124
122
  command :bootstrap do |c|
125
123
  # dry run
126
- c.switch :noop, desc: "Perform a dry run"
127
- c.switch :dryrun, desc: "Perform a dry run"
128
- c.switch :dry_run, desc: "Perform a dry run"
124
+ c.switch :dry, desc: "Perform a dry run"
129
125
 
130
126
  c.action do |global_options, options, args|
131
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
127
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
132
128
 
133
129
  hosts = global_options[:hosts]
134
130
  $app.set_inventory_hosts(hosts)
@@ -141,7 +137,7 @@ module OpsWalrus
141
137
 
142
138
  $app.set_identity_files(id_files)
143
139
 
144
- dry_run = [:noop, :dryrun, :dry_run].any? {|sym| global_options[sym] || options[sym] }
140
+ dry_run = global_options[:dry] || options[:dry]
145
141
  $app.dry_run! if dry_run
146
142
 
147
143
  $app.bootstrap()
@@ -155,12 +151,10 @@ module OpsWalrus
155
151
  c.flag [:u, :user], desc: "Specify the user that the operation will run as"
156
152
 
157
153
  # dry run
158
- c.switch :noop, desc: "Perform a dry run"
159
- c.switch :dryrun, desc: "Perform a dry run"
160
- c.switch :dry_run, desc: "Perform a dry run"
154
+ c.switch :dry, desc: "Perform a dry run"
161
155
 
162
156
  c.action do |global_options, options, args|
163
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
157
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
164
158
 
165
159
  hosts = global_options[:hosts]
166
160
  $app.set_inventory_hosts(hosts)
@@ -176,7 +170,7 @@ module OpsWalrus
176
170
 
177
171
  $app.set_identity_files(id_files)
178
172
 
179
- dry_run = [:noop, :dryrun, :dry_run].any? {|sym| global_options[sym] || options[sym] }
173
+ dry_run = global_options[:dry] || options[:dry]
180
174
  $app.dry_run! if dry_run
181
175
 
182
176
  if options[:pass]
@@ -193,12 +187,10 @@ module OpsWalrus
193
187
  long_desc 'Reboot one or more remote hosts'
194
188
  command :reboot do |c|
195
189
  # dry run
196
- c.switch :noop, desc: "Perform a dry run"
197
- c.switch :dryrun, desc: "Perform a dry run"
198
- c.switch :dry_run, desc: "Perform a dry run"
190
+ c.switch :dry, desc: "Perform a dry run"
199
191
 
200
192
  c.action do |global_options, options, args|
201
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
193
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
202
194
 
203
195
  hosts = global_options[:hosts]
204
196
  $app.set_inventory_hosts(hosts)
@@ -211,7 +203,7 @@ module OpsWalrus
211
203
 
212
204
  $app.set_identity_files(id_files)
213
205
 
214
- dry_run = [:noop, :dryrun, :dry_run].any? {|sym| global_options[sym] || options[sym] }
206
+ dry_run = global_options[:dry] || options[:dry]
215
207
  $app.dry_run! if dry_run
216
208
 
217
209
  exit_status = $app.reboot()
@@ -227,17 +219,16 @@ module OpsWalrus
227
219
  c.switch [:b, :bundle], desc: "Update bundle prior to running the specified operation"
228
220
  c.switch :pass, desc: "Prompt for a sudo password"
229
221
  c.switch :script, desc: "Script mode"
222
+ c.switch [:r, :remote], desc: "Run the operation on the remote hosts"
230
223
 
231
224
  c.flag [:u, :user], desc: "Specify the user that the operation will run as"
232
225
  c.flag [:p, :params], desc: "Either specify a file that contains JSON OR specify a JSON encoded string. In both cases, the JSON represents the runtime arguments (i.e. the params) for the operation. The JSON string must conform to the params schema for the operation being run."
233
226
 
234
227
  # dry run
235
- c.switch :noop, desc: "Perform a dry run"
236
- c.switch :dryrun, desc: "Perform a dry run"
237
- c.switch :dry_run, desc: "Perform a dry run"
228
+ c.switch :dry, desc: "Perform a dry run"
238
229
 
239
230
  c.action do |global_options, options, args|
240
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
231
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
241
232
 
242
233
  hosts = global_options[:hosts]
243
234
  $app.set_inventory_hosts(hosts)
@@ -256,7 +247,7 @@ module OpsWalrus
256
247
 
257
248
  $app.set_identity_files(id_files)
258
249
 
259
- dry_run = [:noop, :dryrun, :dry_run].any? {|sym| global_options[sym] || options[sym] }
250
+ dry_run = global_options[:dry] || options[:dry]
260
251
  $app.dry_run! if dry_run
261
252
 
262
253
  if options[:pass]
@@ -267,7 +258,11 @@ module OpsWalrus
267
258
  $app.script_mode!
268
259
  end
269
260
 
270
- exit_status = $app.run(args, update_bundle: options[:bundle])
261
+ exit_status = if options[:remote]
262
+ $app.run_remote(args, update_bundle: options[:bundle])
263
+ else
264
+ $app.run(args, update_bundle: options[:bundle])
265
+ end
271
266
 
272
267
  exit_now!("error", exit_status) unless exit_status == 0
273
268
  end
@@ -281,7 +276,7 @@ module OpsWalrus
281
276
  long_desc 'Download and bundle the latest versions of dependencies for the current package'
282
277
  c.command :update do |update|
283
278
  update.action do |global_options, options, args|
284
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
279
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
285
280
 
286
281
  $app.bundle_update
287
282
  end
@@ -301,7 +296,7 @@ module OpsWalrus
301
296
  unzip.flag [:o, :output], desc: "Specify the output directory"
302
297
 
303
298
  unzip.action do |global_options, options, args|
304
- $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
299
+ $app.set_log_level(global_options[:loudest] && :trace || global_options[:louder] && :debug || global_options[:loud] && :info || :warn)
305
300
 
306
301
  output_dir = options[:output]
307
302
  zip_file_path = args.first
@@ -81,6 +81,13 @@ module OpsWalrus
81
81
  @_host.to_s
82
82
  end
83
83
 
84
+ def _invoke_remote(ops_file, *args, **kwargs)
85
+ puts "boom"
86
+ is_invocation_a_call_to_package_in_bundle_dir = true
87
+ invocation_context = RemoteImportInvocationContext.new(@runtime_env, self, ops_file, is_invocation_a_call_to_package_in_bundle_dir, ops_prompt_for_sudo_password: !!ssh_password)
88
+ invocation_context._invoke(*args, **kwargs)
89
+ end
90
+
84
91
  # returns [stdout, stderr, exit_status]
85
92
  def _bootstrap_host(print_report = true)
86
93
  # copy over bootstrap shell script
@@ -119,7 +126,7 @@ module OpsWalrus
119
126
  raise Error, "Unable to upload ops bundle to remote host" unless upload_success
120
127
 
121
128
  stdout, _stderr, exit_status = @_host.run_ops(:bundle, "unzip tmpops.zip", in_bundle_root_dir: false)
122
- raise Error, "Unable to unzip ops bundle on remote host" unless exit_status == 0
129
+ raise Error, "Unable to unzip ops bundle on remote host: #{stdout}" unless exit_status == 0
123
130
  tmp_bundle_root_dir = stdout.strip
124
131
  @_host.set_ssh_session_tmp_bundle_root_dir(tmp_bundle_root_dir)
125
132
 
@@ -168,7 +175,8 @@ module OpsWalrus
168
175
  # while trying to reconnect, we expect the following exceptions:
169
176
  # 1. Net::SSH::Disconnect < Net::SSH::Exception with message: "connection closed by remote host"
170
177
  # 2. Errno::ECONNRESET < SystemCallError with message: "Connection reset by peer"
171
- rescue Net::SSH::Disconnect, Errno::ECONNRESET => e
178
+ # 3. Errno::ECONNREFUSED < SystemCallError with message: "Connection refused - connect(2) for 192.168.56.10:22"
179
+ rescue Net::SSH::Disconnect, Errno::ECONNRESET, Errno::ECONNREFUSED => e
172
180
  # noop; we expect these while we're trying to reconnect
173
181
  rescue => e
174
182
  puts "#{e.class} < #{e.class.superclass}"
@@ -214,7 +222,7 @@ module OpsWalrus
214
222
  end
215
223
 
216
224
  # returns the tuple: [stdout, stderr, exit_status]
217
- def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil, log_level: nil, ops_prompt_for_sudo_password: false)
225
+ def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil, ops_prompt_for_sudo_password: false)
218
226
  # description = nil
219
227
 
220
228
  return ["", "", 0] if !desc_or_cmd && !cmd && !block # we were told to do nothing; like hitting enter at the bash prompt; we can do nothing successfully
@@ -241,28 +249,24 @@ module OpsWalrus
241
249
  #cmd = Shellwords.escape(cmd)
242
250
 
243
251
  cmd_id = Random.uuid.split('-').first
244
- # if App.instance.report_mode?
245
252
  output_block = StringIO.open do |io|
246
- io.print Style.blue(host)
247
- io.print " (#{Style.blue(self.alias)})" if self.alias
248
- io.print " | #{Style.magenta(description)}" if description
249
- io.puts
250
- io.print Style.yellow(cmd_id)
251
- io.print Style.green.bold(" > ")
252
- io.puts Style.yellow(cmd)
253
+ if App.instance.info? # this is true if log_level is trace, debug, info
254
+ io.print Style.blue(host)
255
+ io.print " (#{Style.blue(self.alias)})" if self.alias
256
+ io.print " | #{Style.magenta(description)}" if description
257
+ io.puts
258
+ io.print Style.yellow(cmd_id)
259
+ io.print Style.green.bold(" > ")
260
+ io.puts Style.yellow(cmd)
261
+ elsif App.instance.warn? && description
262
+ io.print Style.blue(host)
263
+ io.print " (#{Style.blue(self.alias)})" if self.alias
264
+ io.print " | #{Style.magenta(description)}" if description
265
+ io.puts
266
+ end
253
267
  io.string
254
268
  end
255
- puts output_block
256
-
257
- # puts Style.green("*" * 80)
258
- # if self.alias
259
- # print "[#{Style.blue(self.alias)} | #{Style.blue(host)}] "
260
- # else
261
- # print "[#{Style.blue(host)}] "
262
- # end
263
- # print "#{description}: " if description
264
- # puts Style.yellow("[#{cmd_id}] #{cmd}")
265
- # end
269
+ puts output_block unless output_block.empty?
266
270
 
267
271
  return unless cmd && !cmd.strip.empty?
268
272
 
@@ -277,27 +281,37 @@ module OpsWalrus
277
281
  seconds = t2 - t1
278
282
 
279
283
  output_block = StringIO.open do |io|
280
- if App.instance.info? || log_level == :info
281
- io.puts Style.cyan(out)
282
- io.puts Style.red(err)
283
- elsif App.instance.debug? || log_level == :debug
284
- io.puts Style.cyan(out)
285
- io.puts Style.red(err)
286
- elsif App.instance.trace? || log_level == :trace
287
- io.puts Style.cyan(out)
288
- io.puts Style.red(err)
289
- end
290
- io.print Style.yellow(cmd_id)
291
- io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
292
- if exit_status == 0
293
- io.puts Style.green("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
294
- else
295
- io.puts Style.red("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
284
+ if App.instance.info? # this is true if log_level is trace, debug, info
285
+ if App.instance.trace?
286
+ io.puts Style.cyan(out)
287
+ io.puts Style.red(err)
288
+ elsif App.instance.debug?
289
+ io.puts Style.cyan(out)
290
+ io.puts Style.red(err)
291
+ elsif App.instance.info?
292
+ # io.puts Style.cyan(out)
293
+ # io.puts Style.red(err)
294
+ end
295
+ io.print Style.yellow(cmd_id)
296
+ io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
297
+ if exit_status == 0
298
+ io.puts Style.green("#{exit_status} (success)")
299
+ else
300
+ io.puts Style.red("#{exit_status} (failure)")
301
+ end
302
+ io.puts Style.green("*" * 80)
303
+ elsif App.instance.warn? && description
304
+ io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
305
+ if exit_status == 0
306
+ io.puts Style.green("#{exit_status} (success)")
307
+ else
308
+ io.puts Style.red("#{exit_status} (failure)")
309
+ end
310
+ io.puts Style.green("*" * 80)
296
311
  end
297
- io.puts Style.green("*" * 80)
298
312
  io.string
299
313
  end
300
- puts output_block
314
+ puts output_block unless output_block.empty?
301
315
 
302
316
  [out, err, exit_status]
303
317
  end
@@ -313,18 +327,18 @@ module OpsWalrus
313
327
  # cmd = "OPS_GEM=\"#{OPS_GEM}\" OPSWALRUS_LOCAL_HOSTNAME='#{local_hostname_for_remote_host}'; $OPS_GEM exec --conservative -g opswalrus ops"
314
328
  cmd = "OPSWALRUS_LOCAL_HOSTNAME='#{local_hostname_for_remote_host}' eval #{OPS_CMD}"
315
329
  if App.instance.trace?
316
- cmd << " --trace"
330
+ cmd << " --loudest"
317
331
  elsif App.instance.debug?
318
- cmd << " --debug"
332
+ cmd << " --louder"
319
333
  elsif App.instance.info?
320
- cmd << " --verbose"
334
+ cmd << " --loud"
321
335
  end
322
336
  cmd << " #{ops_command.to_s}"
323
337
  cmd << " #{ops_command_options.to_s}" if ops_command_options
324
338
  cmd << " #{@tmp_bundle_root_dir}" if in_bundle_root_dir
325
339
  cmd << " #{command_arguments}" unless command_arguments.empty?
326
340
 
327
- shell!(cmd, log_level: :info, ops_prompt_for_sudo_password: ops_prompt_for_sudo_password)
341
+ shell!(cmd, ops_prompt_for_sudo_password: ops_prompt_for_sudo_password)
328
342
  end
329
343
 
330
344
  def desc(msg)
@@ -8,9 +8,7 @@ module OpsWalrus
8
8
 
9
9
  attr_accessor :input_mappings # Hash[ String | Regex => String ]
10
10
 
11
- # log_level is one of: :fatal, :error, :warn, :info, :debug, :trace
12
- def initialize(mapping, log_level = nil)
13
- @log_level = log_level
11
+ def initialize(mapping)
14
12
  @input_mappings = mapping
15
13
  end
16
14
 
@@ -63,7 +61,7 @@ module OpsWalrus
63
61
  if new_mapping.empty? || new_mapping == @input_mappings
64
62
  yield self
65
63
  else
66
- yield ScopedMappingInteractionHandler.new(new_mapping, @log_level)
64
+ yield ScopedMappingInteractionHandler.new(new_mapping)
67
65
  end
68
66
  end
69
67
 
@@ -110,12 +110,12 @@ module OpsWalrus
110
110
  Invocation::Error.new(e)
111
111
  end
112
112
 
113
- if result.failure?
114
- App.instance.debug "Ops script error details:"
115
- App.instance.debug "Error: #{result.value}"
116
- App.instance.debug "Status code: #{result.exit_status}"
117
- App.instance.debug @entry_point_ops_file.script.to_s
118
- end
113
+ # if result.failure?
114
+ # App.instance.debug "Ops script error details:"
115
+ # App.instance.debug "Error: #{result.value}"
116
+ # App.instance.debug "Status code: #{result.exit_status}"
117
+ # App.instance.debug @entry_point_ops_file.script.to_s
118
+ # end
119
119
 
120
120
  result
121
121
  end
@@ -263,7 +263,7 @@ module OpsWalrus
263
263
  end
264
264
 
265
265
  # returns the tuple: [stdout, stderr, exit_status]
266
- def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil, log_level: nil)
266
+ def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil)
267
267
  return ["", "", 0] if !desc_or_cmd && !cmd && !block # we were told to do nothing; like hitting enter at the bash prompt; we can do nothing successfully
268
268
 
269
269
  description = desc_or_cmd if cmd || block
@@ -285,7 +285,7 @@ module OpsWalrus
285
285
  end
286
286
  #cmd = Shellwords.escape(cmd)
287
287
 
288
- report_on(@runtime_env.local_hostname, description, cmd, log_level: log_level) do
288
+ report_on(@runtime_env.local_hostname, description, cmd) do
289
289
  if App.instance.dry_run?
290
290
  ["", "", 0]
291
291
  else
@@ -300,19 +300,25 @@ module OpsWalrus
300
300
  end
301
301
  end
302
302
 
303
- def report_on(hostname, description = nil, cmd, log_level: nil)
303
+ def report_on(hostname, description = nil, cmd)
304
304
  cmd_id = Random.uuid.split('-').first
305
305
 
306
306
  output_block = StringIO.open do |io|
307
- io.print Style.blue(hostname)
308
- io.print " | #{Style.magenta(description)}" if description
309
- io.puts
310
- io.print Style.yellow(cmd_id)
311
- io.print Style.green.bold(" > ")
312
- io.puts Style.yellow(cmd)
307
+ if App.instance.info? # this is true if log_level is trace, debug, info
308
+ io.print Style.blue(hostname)
309
+ io.print " | #{Style.magenta(description)}" if description
310
+ io.puts
311
+ io.print Style.yellow(cmd_id)
312
+ io.print Style.green.bold(" > ")
313
+ io.puts Style.yellow(cmd)
314
+ elsif App.instance.warn? && description
315
+ io.print Style.blue(hostname)
316
+ io.print " | #{Style.magenta(description)}" if description
317
+ io.puts
318
+ end
313
319
  io.string
314
320
  end
315
- puts output_block
321
+ puts output_block unless output_block.empty?
316
322
 
317
323
  t1 = Time.now
318
324
  out, err, exit_status = yield
@@ -320,27 +326,37 @@ module OpsWalrus
320
326
  seconds = t2 - t1
321
327
 
322
328
  output_block = StringIO.open do |io|
323
- if App.instance.info? || log_level == :info
324
- io.puts Style.cyan(out)
325
- io.puts Style.red(err)
326
- elsif App.instance.debug? || log_level == :debug
327
- io.puts Style.cyan(out)
328
- io.puts Style.red(err)
329
- elsif App.instance.trace? || log_level == :trace
330
- io.puts Style.cyan(out)
331
- io.puts Style.red(err)
332
- end
333
- io.print Style.yellow(cmd_id)
334
- io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
335
- if exit_status == 0
336
- io.puts Style.green("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
337
- else
338
- io.puts Style.red("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
329
+ if App.instance.info? # this is true if log_level is trace, debug, info
330
+ if App.instance.trace?
331
+ io.puts Style.cyan(out)
332
+ io.puts Style.red(err)
333
+ elsif App.instance.debug?
334
+ io.puts Style.cyan(out)
335
+ io.puts Style.red(err)
336
+ elsif App.instance.info?
337
+ # io.puts Style.cyan(out)
338
+ # io.puts Style.red(err)
339
+ end
340
+ io.print Style.yellow(cmd_id)
341
+ io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
342
+ if exit_status == 0
343
+ io.puts Style.green("#{exit_status} (success)")
344
+ else
345
+ io.puts Style.red("#{exit_status} (failure)")
346
+ end
347
+ io.puts Style.green("*" * 80)
348
+ elsif App.instance.warn? && description
349
+ io.print Style.blue(" | Finished in #{seconds} seconds with exit status ")
350
+ if exit_status == 0
351
+ io.puts Style.green("#{exit_status} (success)")
352
+ else
353
+ io.puts Style.red("#{exit_status} (failure)")
354
+ end
355
+ io.puts Style.green("*" * 80)
339
356
  end
340
- io.puts Style.green("*" * 80)
341
357
  io.string
342
358
  end
343
- puts output_block
359
+ puts output_block unless output_block.empty?
344
360
 
345
361
  [out, err, exit_status]
346
362
  end
@@ -1,5 +1,7 @@
1
1
  require 'json'
2
2
  require 'pathname'
3
+ require 'active_support'
4
+ require 'active_support/core_ext/hash'
3
5
 
4
6
  class String
5
7
  def escape_single_quotes
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.52"
2
+ VERSION = "1.0.53"
3
3
  end
data/opswalrus.gemspec CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ["lib"]
33
33
 
34
34
  # gem dependencies
35
+ spec.add_dependency "activesupport", "~> 7.0"
35
36
  spec.add_dependency "binding_of_caller", "~> 1.0"
36
37
  spec.add_dependency "citrus", "~> 3.0"
37
38
  spec.add_dependency "gli", "~> 2.21"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opswalrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.52
4
+ version: 1.0.53
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-20 00:00:00.000000000 Z
11
+ date: 2023-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: binding_of_caller
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -186,6 +200,7 @@ files:
186
200
  - lib/opswalrus.rb
187
201
  - lib/opswalrus/_bootstrap.ops
188
202
  - lib/opswalrus/_reboot.ops
203
+ - lib/opswalrus/_run_remote.ops
189
204
  - lib/opswalrus/_shell.ops
190
205
  - lib/opswalrus/app.rb
191
206
  - lib/opswalrus/bootstrap.sh