opswalrus 1.0.39 → 1.0.40

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: 413ca26075395f1e533a83af05aae8522f66fb91b96de13d8932f5856053222d
4
- data.tar.gz: cf99aa4a8e71dba2a36129ed3ca2cb51b603d106fd240a0d1d39784e53e6806c
3
+ metadata.gz: 43969fb5bd89993b9f4fb4c127d8a63f7d074d79d08104609b3a43d4df3f6457
4
+ data.tar.gz: beca6e40dcabbe38815ef6ac2fe6581895ba8ea2dcb27ab314ad22d5ff2d47cd
5
5
  SHA512:
6
- metadata.gz: 5ba6764a3018cc959a075b9616d14116ae28c565a53f557864fb6d9ce1b922d75439e79b1563fedd7a4a5cd2a17277243ee8b1d47d5f82c30f6898d08b4088bc
7
- data.tar.gz: f8985876bbc10366839f871818a50d4578728d63f5234ec13479a54801b5771fc8f5e7f9a5c3328c58a508997cd5e12b581b45de1aae759e1a6a71dedeb33118
6
+ metadata.gz: be45244077503ac67da072c8d41cad8800553cb9dc243d49904de29588c20a93317543b3d2d2d97a8c7a74ca0a1abc6c0d2fa5d4187b1fe34d863e1e3e558218
7
+ data.tar.gz: 3cd42b3c126aef7dcec443c7f14fe9ee308da1d153148430b2413fe4166c4a214c43b0e368b485a4b3dd6cddf9c3047f778e55dbd4b99dc79697d75eaf910c72
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.39)
5
- amazing_print (~> 1.5)
4
+ opswalrus (1.0.40)
6
5
  bcrypt_pbkdf (~> 1.1)
7
6
  binding_of_caller (~> 1.0)
8
7
  citrus (~> 3.0)
@@ -20,7 +19,6 @@ GEM
20
19
  specs:
21
20
  addressable (2.8.5)
22
21
  public_suffix (>= 2.0.2, < 6.0)
23
- amazing_print (1.5.0)
24
22
  bcrypt_pbkdf (1.1.0)
25
23
  binding_of_caller (1.0.0)
26
24
  debug_inspector (>= 0.0.1)
data/lib/opswalrus/app.rb CHANGED
@@ -49,7 +49,6 @@ module OpsWalrus
49
49
  # @logger.debug Style.yellow("debug"), foo: "bar", baz: {qux: "quux"}
50
50
  # @logger.trace Style.yellow("trace"), foo: "bar", baz: {qux: "quux"}
51
51
 
52
- @verbose = false
53
52
  @sudo_user = nil
54
53
  @sudo_password = nil
55
54
  @identity_file_paths = []
@@ -124,38 +123,53 @@ module OpsWalrus
124
123
  @logger.level = log_level
125
124
  end
126
125
 
127
- def verbose?
128
- [:info, :debug, :trace].include? @logger.level
129
- end
130
-
131
- def debug?
132
- [:debug, :trace].include? @logger.level
133
- end
134
-
135
126
  def fatal(*args)
136
127
  @logger.fatal(*args)
137
128
  end
129
+ def fatal?
130
+ @logger.fatal?
131
+ end
138
132
 
139
133
  def error(*args)
140
134
  @logger.error(*args)
141
135
  end
136
+ def error?
137
+ @logger.error?
138
+ end
142
139
 
143
140
  def warn(*args)
144
141
  @logger.warn(*args)
145
142
  end
143
+ alias_method :important, :warn # warn means important
144
+ def warn?
145
+ @logger.warn?
146
+ end
146
147
 
147
- def log(*args)
148
+ def info(*args)
148
149
  @logger.info(*args)
149
150
  end
150
- alias_method :info, :log
151
+ alias_method :log, :info
152
+ def info?
153
+ @logger.info?
154
+ end
151
155
 
152
156
  def debug(*args)
153
157
  @logger.debug(*args)
154
158
  end
159
+ def debug?
160
+ @logger.debug?
161
+ end
155
162
 
156
163
  def trace(*args)
157
164
  @logger.trace(*args)
158
165
  end
166
+ def trace?
167
+ @logger.trace?
168
+ end
169
+
170
+ def verbose?
171
+ info? || debug? || trace?
172
+ end
159
173
 
160
174
  def set_pwd(pwd)
161
175
  @pwd = pwd.to_pathname
@@ -181,7 +195,6 @@ module OpsWalrus
181
195
  def prompt_sudo_password
182
196
  password = IO::console.getpass(LOCAL_SUDO_PASSWORD_PROMPT)
183
197
  set_sudo_password(password)
184
- # puts "sudo password = |#{password}|"
185
198
  nil
186
199
  end
187
200
 
@@ -223,25 +236,19 @@ module OpsWalrus
223
236
 
224
237
  ops_file = load_entry_point_ops_file(ops_file_path, tmp_bundle_root_dir)
225
238
 
226
- if @verbose
227
- puts "Running: #{ops_file.ops_file_path}"
228
- end
239
+ debug "Running: #{ops_file.ops_file_path}"
229
240
 
230
241
  op = OperationRunner.new(self, ops_file)
231
242
  result = op.run(operation_kv_args, params_json_hash: @params)
232
243
  exit_status = result.exit_status
233
244
 
234
- if @verbose
235
- puts "Op exit_status"
236
- puts exit_status
245
+ debug "Op exit_status"
246
+ debug exit_status
237
247
 
238
- puts "Op output"
239
- puts JSON.pretty_generate(result.value)
240
- end
248
+ debug "Op output"
249
+ debug JSON.pretty_generate(result.value)
241
250
 
242
- if script_mode?
243
- puts JSON.pretty_generate(result.value)
244
- end
251
+ puts JSON.pretty_generate(result.value)
245
252
 
246
253
  exit_status
247
254
  ensure
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
3
  export PATH="$HOME/.local/share/rtx/bin:$PATH" # this is key for activating rtx without running `eval "$($RTX activate bash)"`
4
+ # eval "$(rtx activate bash)"
4
5
  RTX="$HOME/.local/share/rtx/bin/rtx"
5
6
  rtx_init() { eval "$($RTX activate bash)"; }
6
7
  # RTX_RUBY="$HOME/.local/share/rtx/bin/rtx x ruby -- ruby"
@@ -27,7 +28,7 @@ if [ -x $RTX ]; then
27
28
  # make sure the latest opswalrus gem is installed
28
29
  # todo: figure out how to install this differently, so that test versions will work
29
30
  # gem install opswalrus
30
- $GEM_CMD install opswalrus
31
+ # $GEM_CMD install opswalrus
31
32
  $RTX reshim
32
33
 
33
34
  exit 0
data/lib/opswalrus/cli.rb CHANGED
@@ -22,19 +22,17 @@ module OpsWalrus
22
22
  on_error do |exception|
23
23
  next(false) if exception.is_a? GLI::CustomExit
24
24
 
25
- puts "catchall exception handler:"
26
- puts exception.message
27
- puts exception.backtrace.join("\n")
25
+ $app.fatal "catchall exception handler:"
26
+ $app.fatal exception.message
27
+ $app.fatal exception.backtrace.join("\n")
28
28
  false # disable built-in exception handling
29
29
  end
30
30
 
31
31
  program_desc 'ops is an operation runner'
32
32
 
33
- desc 'Be verbose'
34
- switch [:v, :verbose]
35
-
36
- desc 'Turn on debug mode'
37
- switch [:d, :debug]
33
+ switch [:v, :verbose], desc: "Verbose output"
34
+ switch :debug, desc: "Debug output"
35
+ switch :trace, desc: "Trace output"
38
36
 
39
37
  switch :noop, desc: "Perform a dry run"
40
38
  switch :dryrun, desc: "Perform a dry run"
@@ -63,8 +61,7 @@ module OpsWalrus
63
61
  hosts = global_options[:hosts]
64
62
  tags = global_options[:tags]
65
63
 
66
- log_level = global_options[:debug] && :trace || global_options[:verbose] && :debug || :info
67
- $app.set_log_level(log_level)
64
+ $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
68
65
 
69
66
  $app.report_inventory(hosts, tags: tags)
70
67
  end
@@ -131,8 +128,7 @@ module OpsWalrus
131
128
  c.switch :dry_run, desc: "Perform a dry run"
132
129
 
133
130
  c.action do |global_options, options, args|
134
- log_level = global_options[:debug] && :trace || global_options[:verbose] && :debug || :info
135
- $app.set_log_level(log_level)
131
+ $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
136
132
 
137
133
  hosts = global_options[:hosts]
138
134
  tags = global_options[:tags]
@@ -168,8 +164,7 @@ module OpsWalrus
168
164
  c.switch :dry_run, desc: "Perform a dry run"
169
165
 
170
166
  c.action do |global_options, options, args|
171
- log_level = global_options[:debug] && :trace || global_options[:verbose] && :debug || :info
172
- $app.set_log_level(log_level)
167
+ $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
173
168
 
174
169
  hosts = global_options[:hosts]
175
170
  $app.set_inventory_hosts(hosts)
@@ -213,8 +208,7 @@ module OpsWalrus
213
208
  long_desc 'Download and bundle the latest versions of dependencies for the current package'
214
209
  c.command :update do |update|
215
210
  update.action do |global_options, options, args|
216
- log_level = global_options[:debug] && :trace || global_options[:verbose] && :debug || :info
217
- $app.set_log_level(log_level)
211
+ $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
218
212
 
219
213
  $app.bundle_update
220
214
  end
@@ -234,8 +228,7 @@ module OpsWalrus
234
228
  unzip.flag [:o, :output], desc: "Specify the output directory"
235
229
 
236
230
  unzip.action do |global_options, options, args|
237
- log_level = global_options[:debug] && :trace || global_options[:verbose] && :debug || :info
238
- $app.set_log_level(log_level)
231
+ $app.set_log_level(global_options[:trace] && :trace || global_options[:debug] && :debug || global_options[:verbose] && :info || :warn)
239
232
 
240
233
  output_dir = options[:output]
241
234
  zip_file_path = args.first
@@ -51,7 +51,6 @@ module OpsWalrus
51
51
  sibling_symbol_table |= ops_file.dirname.glob("*").select(&:directory?).map {|dir_path| dir_path.basename.to_s } # Namespaces
52
52
  sibling_symbol_table.each do |symbol_name|
53
53
  unless methods_defined.include? symbol_name
54
- # puts "2. defining: #{symbol_name}(...)"
55
54
  klass.define_method(symbol_name) do |*args, **kwargs, &block|
56
55
  App.instance.trace "resolving implicit import: #{symbol_name}"
57
56
  namespace_or_ops_file = @runtime_env.resolve_sibling_symbol(ops_file, symbol_name)
@@ -144,7 +143,7 @@ module OpsWalrus
144
143
  end
145
144
 
146
145
  # returns the tuple: [stdout, stderr, exit_status]
147
- def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil)
146
+ def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil, log_level: nil)
148
147
  # description = nil
149
148
 
150
149
  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
@@ -170,57 +169,83 @@ module OpsWalrus
170
169
 
171
170
  #cmd = Shellwords.escape(cmd)
172
171
 
173
- if App.instance.report_mode?
174
- puts Style.green("*" * 80)
175
- if self.alias
176
- print "[#{Style.blue(self.alias)} | #{Style.blue(host)}] "
177
- else
178
- print "[#{Style.blue(host)}] "
179
- end
180
- print "#{description}: " if description
181
- puts Style.yellow(cmd)
182
- end
172
+ cmd_id = Random.uuid.split('-').first
173
+ # if App.instance.report_mode?
174
+ puts Style.green("*" * 80)
175
+ print Style.blue(host)
176
+ print " (#{Style.blue(self.alias)})" if self.alias
177
+ print " | #{Style.magenta(description)}" if description
178
+ puts
179
+ print Style.yellow(cmd_id)
180
+ print Style.green.bold(" > ")
181
+ puts Style.yellow(cmd)
182
+
183
+ # puts Style.green("*" * 80)
184
+ # if self.alias
185
+ # print "[#{Style.blue(self.alias)} | #{Style.blue(host)}] "
186
+ # else
187
+ # print "[#{Style.blue(host)}] "
188
+ # end
189
+ # print "#{description}: " if description
190
+ # puts Style.yellow("[#{cmd_id}] #{cmd}")
191
+ # end
183
192
 
184
193
  return unless cmd && !cmd.strip.empty?
185
194
 
186
- # puts "shell: #{cmd}"
187
- # puts "shell: #{cmd.inspect}"
188
- # puts "sudo_password: #{sudo_password}"
189
-
190
- if App.instance.dry_run?
195
+ t1 = Time.now
196
+ out, err, exit_status = if App.instance.dry_run?
191
197
  ["", "", 0]
192
198
  else
193
199
  sshkit_cmd = execute_cmd(cmd, input: input)
194
200
  [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
195
201
  end
196
- end
202
+ t2 = Time.now
203
+ seconds = t2 - t1
204
+
205
+ if App.instance.info? || log_level == :info
206
+ puts Style.cyan(out)
207
+ puts Style.red(err)
208
+ elsif App.instance.debug? || log_level == :debug
209
+ puts Style.cyan(out)
210
+ puts Style.red(err)
211
+ elsif App.instance.trace? || log_level == :trace
212
+ puts Style.cyan(out)
213
+ puts Style.red(err)
214
+ end
215
+ print Style.yellow(cmd_id)
216
+ print Style.blue(" | Finished in #{seconds} seconds with exit status ")
217
+ if exit_status == 0
218
+ puts Style.green("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
219
+ else
220
+ puts Style.red("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
221
+ end
197
222
 
198
- # def init_brew
199
- # execute('eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"')
200
- # end
223
+ [out, err, exit_status]
224
+ end
201
225
 
202
226
  # runs the specified ops command with the specified command arguments
203
- def run_ops(ops_command, ops_command_options = nil, command_arguments, in_bundle_root_dir: true, verbose: false)
204
- # e.g. /home/linuxbrew/.linuxbrew/bin/gem exec -g opswalrus ops bundle unzip tmpops.zip
205
- # e.g. /home/linuxbrew/.linuxbrew/bin/gem exec -g opswalrus ops run echo.ops args:foo args:bar
206
-
207
- # cmd = "/home/linuxbrew/.linuxbrew/bin/gem exec -g opswalrus ops"
227
+ def run_ops(ops_command, ops_command_options = nil, command_arguments, in_bundle_root_dir: true)
208
228
  local_hostname_for_remote_host = if self.alias
209
- "#{self.alias} | #{host}"
229
+ "#{host} (#{self.alias})"
210
230
  else
211
231
  host
212
232
  end
213
233
 
214
- # cmd = "OPSWALRUS_LOCAL_HOSTNAME='#{local_hostname_for_remote_host}'; /home/linuxbrew/.linuxbrew/bin/gem exec --conservative -g opswalrus ops"
215
234
  # cmd = "OPS_GEM=\"#{OPS_GEM}\" OPSWALRUS_LOCAL_HOSTNAME='#{local_hostname_for_remote_host}'; $OPS_GEM exec --conservative -g opswalrus ops"
216
235
  cmd = "OPSWALRUS_LOCAL_HOSTNAME='#{local_hostname_for_remote_host}' eval #{OPS_CMD}"
217
- cmd << " -v" if verbose
236
+ if App.instance.info?
237
+ cmd << " --verbose"
238
+ elsif App.instance.debug?
239
+ cmd << " --debug"
240
+ elsif App.instance.trace?
241
+ cmd << " --trace"
242
+ end
218
243
  cmd << " #{ops_command.to_s}"
219
244
  cmd << " #{ops_command_options.to_s}" if ops_command_options
220
245
  cmd << " #{@tmp_bundle_root_dir}" if in_bundle_root_dir
221
246
  cmd << " #{command_arguments}" unless command_arguments.empty?
222
247
 
223
- shell!(cmd)
248
+ shell!(cmd, log_level: :info)
224
249
  end
225
250
 
226
251
  def desc(msg)
@@ -391,13 +416,15 @@ module OpsWalrus
391
416
 
392
417
  def execute(*args, input: nil)
393
418
  @runtime_env.handle_input(input, ssh_password) do |interaction_handler|
394
- @sshkit_backend.capture(*args, interaction_handler: interaction_handler, verbosity: :info)
419
+ # @sshkit_backend.capture(*args, interaction_handler: interaction_handler, verbosity: SSHKit.config.output_verbosity)
420
+ @sshkit_backend.capture(*args, interaction_handler: interaction_handler)
395
421
  end
396
422
  end
397
423
 
398
424
  def execute_cmd(*args, input: nil)
399
425
  @runtime_env.handle_input(input, ssh_password) do |interaction_handler|
400
- @sshkit_backend.execute_cmd(*args, interaction_handler: interaction_handler, verbosity: :info)
426
+ # @sshkit_backend.execute_cmd(*args, interaction_handler: interaction_handler, verbosity: SSHKit.config.output_verbosity)
427
+ @sshkit_backend.execute_cmd(*args, interaction_handler: interaction_handler)
401
428
  end
402
429
  end
403
430
 
@@ -168,20 +168,18 @@ module OpsWalrus
168
168
 
169
169
  def decrypt(decrypted_file_path = nil)
170
170
  decrypted_file_path ||= @hosts_file_path
171
- puts "Decrypting #{@hosts_file_path} -> #{decrypted_file_path}."
171
+ App.instance.debug "Decrypting #{@hosts_file_path} -> #{decrypted_file_path}."
172
172
  raise("Path to age identity not specified") if App.instance.identity_file_paths.empty?
173
173
  decrypt_secrets!
174
174
  File.write(decrypted_file_path, to_yaml)
175
- # puts to_yaml
176
175
  end
177
176
 
178
177
  def encrypt(encrypted_file_path = nil)
179
178
  encrypted_file_path ||= @hosts_file_path
180
- puts "Encrypting #{@hosts_file_path} -> #{encrypted_file_path}."
179
+ App.instance.debug "Encrypting #{@hosts_file_path} -> #{encrypted_file_path}."
181
180
  raise("Path to age identity not specified") if App.instance.identity_file_paths.empty?
182
181
  encrypt_secrets!
183
182
  File.write(encrypted_file_path, to_yaml)
184
- # puts to_yaml
185
183
  end
186
184
  end
187
185
 
@@ -231,7 +229,7 @@ module OpsWalrus
231
229
  when Array
232
230
  ref.map {|audience_id_reference| dereference(audience_id_reference) }.flatten.compact.uniq
233
231
  when Nil
234
- puts "ID #{audience_id_reference} does not appear in the list of known public key identifiers"
232
+ App.instance.warn "ID #{audience_id_reference} does not appear in the list of known public key identifiers"
235
233
  nil
236
234
  else
237
235
  raise "ID reference #{audience_id_reference} corresponds to an unknown type of public key or transitive ID reference: #{ref.inspect}"
@@ -372,7 +370,6 @@ module OpsWalrus
372
370
  # coder.represent_scalar(nil, @public_key)
373
371
 
374
372
  # coder.scalar = @public_key
375
- # puts @ids.inspect
376
373
  single_line_ids = @ids.join(", ")
377
374
  if single_line_ids.size <= 80
378
375
  coder['ids'] = single_line_ids
@@ -85,9 +85,6 @@ module OpsWalrus
85
85
 
86
86
  def debug(message)
87
87
  App.instance.debug(message)
88
- if [:fatal, :error, :warn, :info, :debug, :trace].include? @log_level
89
- SSHKit.config.output.send(@log_level, message)
90
- end
91
88
  end
92
89
 
93
90
  end
@@ -39,7 +39,7 @@ module SSHKit
39
39
  handle_data_for_stdout(output, cmd, buffer, stdin, true)
40
40
  stdout.close
41
41
  rescue => e
42
- puts "closing PTY due to unexpected error: #{e.message}"
42
+ App.instance.error "closing PTY due to unexpected error: #{e.message}"
43
43
  handle_data_for_stdout(output, cmd, buffer, stdin, true)
44
44
  stdout.close
45
45
  # puts e.message
@@ -73,7 +73,7 @@ module SSHKit
73
73
  handle_data_for_stderr(output, cmd, buffer, stdin, true)
74
74
  stderr.close
75
75
  rescue => e
76
- puts "closing PTY due to unexpected error: #{e.message}"
76
+ App.instance.error "closing PTY due to unexpected error: #{e.message}"
77
77
  handle_data_for_stderr(output, cmd, buffer, stdin, true)
78
78
  stderr.close
79
79
  # puts e.message
@@ -44,7 +44,7 @@ module SSHKit
44
44
  handle_data_for_stdout(output, cmd, buffer, stdin, true)
45
45
  stdout.close
46
46
  rescue => e
47
- puts "closing PTY due to unexpected error: #{e.message}"
47
+ App.instance.error "closing PTY due to unexpected error: #{e.message}"
48
48
  handle_data_for_stdout(output, cmd, buffer, stdin, true)
49
49
  stdout.close
50
50
  # puts e.message
@@ -83,10 +83,8 @@ module OpsWalrus
83
83
  def run(runtime_kv_args, params_json_hash: nil)
84
84
  params_hash = build_params_hash(runtime_kv_args, params_json_hash: params_json_hash)
85
85
 
86
- if app.debug?
87
- App.instance.trace "Script:"
88
- App.instance.trace @entry_point_ops_file.script
89
- end
86
+ App.instance.trace "Script:"
87
+ App.instance.trace @entry_point_ops_file.script
90
88
 
91
89
  result = begin
92
90
  # update the bundle for the package
@@ -112,7 +110,7 @@ module OpsWalrus
112
110
  Invocation::Error.new(e)
113
111
  end
114
112
 
115
- if app.debug? && result.failure?
113
+ if result.failure?
116
114
  App.instance.debug "Ops script error details:"
117
115
  App.instance.debug "Error: #{result.value}"
118
116
  App.instance.debug "Status code: #{result.exit_status}"
@@ -47,8 +47,7 @@ module OpsWalrus
47
47
  end
48
48
 
49
49
  def lazy_load_file
50
- # puts "OpsFile#lazy_load_file for #{ops_file_path}"
51
- # puts caller
50
+ App.instance.trace "OpsFile#lazy_load_file for #{@ops_file_path}"
52
51
  yaml, ruby_script = if @ops_file_path.exist?
53
52
  parse(File.read(@ops_file_path))
54
53
  end || ["", ""]
@@ -166,7 +165,7 @@ module OpsWalrus
166
165
  package_uri = import_str
167
166
  if Git.repo?(package_uri) # ops file has imported an ad-hoc git repo
168
167
  destination_package_path = app.bundler.dynamic_package_path_for_git_package(package_uri)
169
- # puts "DynamicPackageImportReference: #{local_name} -> #{destination_package_path}"
168
+ App.instance.trace "DynamicPackageImportReference: #{local_name} -> #{destination_package_path}"
170
169
  return DynamicPackageImportReference.new(local_name, DynamicPackageReference.new(local_name, package_uri, nil))
171
170
  end
172
171
 
@@ -110,7 +110,7 @@ module OpsWalrus
110
110
  sibling_symbol_table_names = Set.new
111
111
  sibling_symbol_table_names |= ops_file.dirname.glob("*.ops").map {|ops_file_path| ops_file_path.basename(".ops").to_s } # OpsFiles
112
112
  sibling_symbol_table_names |= ops_file.dirname.glob("*").select(&:directory?).map {|dir_path| dir_path.basename.to_s } # Namespaces
113
- # puts "sibling_symbol_table_names=#{sibling_symbol_table_names}"
113
+ # App.instance.trace "sibling_symbol_table_names=#{sibling_symbol_table_names}"
114
114
  App.instance.trace "methods_defined=#{methods_defined}"
115
115
  sibling_symbol_table_names.each do |symbol_name|
116
116
  unless methods_defined.include? symbol_name
@@ -134,8 +134,6 @@ module OpsWalrus
134
134
  # - @params
135
135
  # - #host_proxy_class
136
136
  # - #backend
137
- # - #debug?
138
- # - #verbose?
139
137
  # - all the dynamically defined methods in the subclass of Invocation
140
138
  invoke_method_definition = <<~INVOKE_METHOD
141
139
  def _invoke(runtime_env, hashlike_params)
@@ -167,14 +165,6 @@ module OpsWalrus
167
165
  @runtime_env.pty
168
166
  end
169
167
 
170
- def debug?
171
- @runtime_env.debug?
172
- end
173
-
174
- def verbose?
175
- @runtime_env.verbose?
176
- end
177
-
178
168
  def host_proxy_class
179
169
  @ops_file.host_proxy_class
180
170
  end
@@ -1,5 +1,6 @@
1
1
  require 'shellwords'
2
2
  require 'stringio'
3
+ require 'random/formatter'
3
4
 
4
5
  require 'sshkit'
5
6
  require 'sshkit/dsl'
@@ -73,28 +74,28 @@ module OpsWalrus
73
74
 
74
75
  retval
75
76
  rescue SSHKit::Command::Failed => e
76
- puts "[!] Command failed:"
77
- puts e.message
77
+ App.instance.error "[!] Command failed:"
78
+ App.instance.error e.message
78
79
  rescue Net::SSH::ConnectionTimeout
79
- puts "[!] The host '#{host}' not alive!"
80
+ App.instance.error "[!] The host '#{host}' not alive!"
80
81
  rescue Net::SSH::Timeout
81
- puts "[!] The host '#{host}' disconnected/timeouted unexpectedly!"
82
+ App.instance.error "[!] The host '#{host}' disconnected/timeouted unexpectedly!"
82
83
  rescue Errno::ECONNREFUSED
83
- puts "[!] Incorrect port #{port} for #{host}"
84
+ App.instance.error "[!] Incorrect port #{port} for #{host}"
84
85
  rescue Net::SSH::HostKeyMismatch => e
85
- puts "[!] The host fingerprint does not match the last observed fingerprint for #{host}"
86
- puts e.message
87
- puts "You might try `ssh-keygen -f ~/.ssh/known_hosts -R \"#{host}\"`"
86
+ App.instance.error "[!] The host fingerprint does not match the last observed fingerprint for #{host}"
87
+ App.instance.error e.message
88
+ App.instance.error "You might try `ssh-keygen -f ~/.ssh/known_hosts -R \"#{host}\"`"
88
89
  rescue Net::SSH::AuthenticationFailed
89
- puts "Wrong Password: #{host} | #{user}:#{password}"
90
+ App.instance.error "Wrong Password: #{host} | #{user}:#{password}"
90
91
  rescue Net::SSH::Authentication::DisallowedMethod
91
- puts "[!] The host '#{host}' doesn't accept password authentication method."
92
+ App.instance.error "[!] The host '#{host}' doesn't accept password authentication method."
92
93
  rescue Errno::EHOSTUNREACH => e
93
- puts "[!] The host '#{host}' is unreachable"
94
+ App.instance.error "[!] The host '#{host}' is unreachable"
94
95
  rescue => e
95
- puts e.class
96
- puts e.message
97
- puts e.backtrace.join("\n")
96
+ App.instance.error e.class
97
+ App.instance.error e.message
98
+ App.instance.error e.backtrace.join("\n")
98
99
  ensure
99
100
  host.clear_ssh_session
100
101
  end
@@ -124,28 +125,28 @@ module OpsWalrus
124
125
 
125
126
  retval
126
127
  rescue SSHKit::Command::Failed => e
127
- puts "[!] Command failed:"
128
- puts e.message
128
+ App.instance.error "[!] Command failed:"
129
+ App.instance.error e.message
129
130
  rescue Net::SSH::ConnectionTimeout
130
- puts "[!] The host '#{host}' not alive!"
131
+ App.instance.error "[!] The host '#{host}' not alive!"
131
132
  rescue Net::SSH::Timeout
132
- puts "[!] The host '#{host}' disconnected/timeouted unexpectedly!"
133
+ App.instance.error "[!] The host '#{host}' disconnected/timeouted unexpectedly!"
133
134
  rescue Errno::ECONNREFUSED
134
- puts "[!] Incorrect port #{port} for #{host}"
135
+ App.instance.error "[!] Incorrect port #{port} for #{host}"
135
136
  rescue Net::SSH::HostKeyMismatch => e
136
- puts "[!] The host fingerprint does not match the last observed fingerprint for #{host}"
137
- puts e.message
138
- puts "You might try `ssh-keygen -f ~/.ssh/known_hosts -R \"#{host}\"`"
137
+ App.instance.error "[!] The host fingerprint does not match the last observed fingerprint for #{host}"
138
+ App.instance.error e.message
139
+ App.instance.error "You might try `ssh-keygen -f ~/.ssh/known_hosts -R \"#{host}\"`"
139
140
  rescue Net::SSH::AuthenticationFailed
140
- puts "Wrong Password: #{host} | #{user}:#{password}"
141
+ App.instance.error "Wrong Password: #{host} | #{user}:#{password}"
141
142
  rescue Net::SSH::Authentication::DisallowedMethod
142
- puts "[!] The host '#{host}' doesn't accept password authentication method."
143
+ App.instance.error "[!] The host '#{host}' doesn't accept password authentication method."
143
144
  rescue Errno::EHOSTUNREACH => e
144
- puts "[!] The host '#{host}' is unreachable"
145
+ App.instance.error "[!] The host '#{host}' is unreachable"
145
146
  rescue => e
146
- puts e.class
147
- puts e.message
148
- puts e.backtrace.join("\n")
147
+ App.instance.error e.class
148
+ App.instance.error e.message
149
+ App.instance.error e.backtrace.join("\n")
149
150
  ensure
150
151
  host.clear_ssh_session
151
152
  end
@@ -182,7 +183,6 @@ module OpsWalrus
182
183
  package_reference = ops_file.package_file&.dependency(local_package_name)
183
184
  raise Error, "Unknown package reference: #{local_package_name}" unless package_reference
184
185
  import_reference = PackageDependencyReference.new(local_package_name, package_reference)
185
- # puts "import: #{import_reference.inspect}"
186
186
  namespace_or_ops_file = @runtime_env.resolve_import_reference(ops_file, import_reference)
187
187
  raise SymbolResolutionError, "Import reference '#{import_reference.summary}' not in load path for #{ops_file.ops_file_path}" unless namespace_or_ops_file
188
188
  invocation_context = LocalImportInvocationContext.new(@runtime_env, namespace_or_ops_file)
@@ -223,7 +223,7 @@ module OpsWalrus
223
223
  end
224
224
 
225
225
  # returns the tuple: [stdout, stderr, exit_status]
226
- def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil)
226
+ def shell!(desc_or_cmd = nil, cmd = nil, block = nil, input: nil, log_level: nil)
227
227
  # description = nil
228
228
 
229
229
  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
@@ -250,31 +250,55 @@ module OpsWalrus
250
250
 
251
251
  #cmd = Shellwords.escape(cmd)
252
252
 
253
- # puts "shell! self: #{self.inspect}"
253
+ cmd_id = Random.uuid.split('-').first
254
254
 
255
- if App.instance.report_mode?
256
- puts Style.green("*" * 80)
257
- print "[#{Style.blue(@runtime_env.local_hostname)}] "
258
- print "#{description}: " if description
259
- puts Style.yellow(cmd)
260
- end
255
+ # if App.instance.report_mode?
256
+ puts Style.green("*" * 80)
257
+ print Style.blue(@runtime_env.local_hostname)
258
+ print " | #{Style.magenta(description)}" if description
259
+ puts
260
+ print Style.yellow(cmd_id)
261
+ print Style.green.bold(" > ")
262
+ puts Style.yellow(cmd)
263
+ # end
261
264
 
262
265
  return unless cmd && !cmd.strip.empty?
263
266
 
264
- if App.instance.dry_run?
267
+ t1 = Time.now
268
+ out, err, exit_status = if App.instance.dry_run?
265
269
  ["", "", 0]
266
270
  else
267
271
  sshkit_cmd = @runtime_env.handle_input(input) do |interaction_handler|
268
272
  # 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: :info)
273
+ # backend.execute_cmd(cmd, interaction_handler: interaction_handler, verbosity: SSHKit.config.output_verbosity)
274
+ backend.execute_cmd(cmd, interaction_handler: interaction_handler)
270
275
  end
271
276
  [sshkit_cmd.full_stdout, sshkit_cmd.full_stderr, sshkit_cmd.exit_status]
272
277
  end
273
- end
278
+ t2 = Time.now
279
+ seconds = t2 - t1
280
+
281
+ if App.instance.info? || log_level == :info
282
+ puts Style.cyan(out)
283
+ puts Style.red(err)
284
+ elsif App.instance.debug? || log_level == :debug
285
+ puts Style.cyan(out)
286
+ puts Style.red(err)
287
+ elsif App.instance.trace? || log_level == :trace
288
+ puts Style.cyan(out)
289
+ puts Style.red(err)
290
+ end
291
+ print Style.yellow(cmd_id)
292
+ print Style.blue(" | Finished in #{seconds} seconds with exit status ")
293
+ if exit_status == 0
294
+ puts Style.green("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
295
+ else
296
+ puts Style.red("#{exit_status} (#{exit_status == 0 ? 'success' : 'failure'})")
297
+ end
298
+
274
299
 
275
- # def init_brew
276
- # execute('eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"')
277
- # end
300
+ [out, err, exit_status]
301
+ end
278
302
 
279
303
  end
280
304
 
@@ -207,12 +207,12 @@ module OpsWalrus
207
207
  def resolve_import_reference(origin_ops_file, import_reference)
208
208
  resolved_namespace_or_ops_file = case import_reference
209
209
  when PackageDependencyReference
210
- # puts "root namespace: #{@root_namespace.symbol_table}"
210
+ # App.instance.trace "root namespace: #{@root_namespace.symbol_table}"
211
211
  @root_namespace.resolve_symbol(import_reference.package_reference.import_resolution_dirname) # returns the Namespace associated with the bundled package import_resolution_dirname (i.e. the local name)
212
212
  when DynamicPackageImportReference
213
213
  dynamic_package_reference = import_reference.package_reference
214
214
  @dynamic_package_additions_memo[dynamic_package_reference] ||= begin
215
- # puts "Downloading dynamic package: #{dynamic_package_reference.inspect}"
215
+ # App.instance.trace "Downloading dynamic package: #{dynamic_package_reference.inspect}"
216
216
  App.instance.debug("Downloading dynamic package: #{dynamic_package_reference}")
217
217
  dynamically_added_package_dir = @runtime_env.app.bundler.download_git_package(dynamic_package_reference.package_uri, dynamic_package_reference.version)
218
218
  dynamically_add_new_package_dir(dynamically_added_package_dir)
@@ -267,15 +267,16 @@ module OpsWalrus
267
267
  SSHKit.config.use_format :blackhole
268
268
  SSHKit.config.output_verbosity = :info
269
269
 
270
- if app.debug?
271
- SSHKit.config.use_format :pretty
272
- # SSHKit.config.use_format :simpletext
273
- SSHKit.config.output_verbosity = :debug
274
- elsif app.verbose?
275
- SSHKit.config.use_format :pretty
276
- # SSHKit.config.use_format :dot
277
- SSHKit.config.output_verbosity = :info
278
- end
270
+ # if app.info?
271
+ # SSHKit.config.use_format :pretty
272
+ # SSHKit.config.output_verbosity = :info
273
+ # elsif app.debug?
274
+ # SSHKit.config.use_format :pretty
275
+ # SSHKit.config.output_verbosity = :debug
276
+ # elsif app.trace?
277
+ # SSHKit.config.use_format :pretty
278
+ # SSHKit.config.output_verbosity = :debug
279
+ # end
279
280
 
280
281
  SSHKit::Backend::Netssh.configure do |ssh|
281
282
  ssh.pty = true # necessary for interaction with sudo on the remote host
@@ -292,14 +293,6 @@ module OpsWalrus
292
293
  SSHKit::Backend::Netssh.pool.idle_timeout = 1 # seconds
293
294
  end
294
295
 
295
- def debug?
296
- @app.debug?
297
- end
298
-
299
- def verbose?
300
- @app.verbose?
301
- end
302
-
303
296
  def local_hostname
304
297
  @app.local_hostname
305
298
  end
@@ -9,10 +9,10 @@ require_relative 'local_pty_backend'
9
9
  module SSHKit
10
10
  module Backend
11
11
  class Abstract
12
- def execute(*args)
13
- options = { raise_on_non_zero_exit: false }.merge(args.extract_options!)
14
- create_command_and_execute(args, options).success?
15
- end
12
+ # def execute(*args)
13
+ # options = { verbosity: :debug, raise_on_non_zero_exit: false }.merge(args.extract_options!)
14
+ # create_command_and_execute(args, options).success?
15
+ # end
16
16
 
17
17
  def execute_cmd(*args)
18
18
  options = { verbosity: :debug, strip: true, raise_on_non_zero_exit: false }.merge(args.extract_options!)
@@ -21,6 +21,12 @@ module SSHKit
21
21
  end
22
22
  end
23
23
 
24
+ # module Formatter
25
+ # class Pretty < Abstract
26
+
27
+ # end
28
+ # end
29
+
24
30
  module Runner
25
31
  class Sequential < Abstract
26
32
  def run_backend(host, &block)
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.39"
2
+ VERSION = "1.0.40"
3
3
  end
@@ -99,7 +99,6 @@ end
99
99
  # # m = TemplateLang.parse("abc; {{ 'foo' * bar }} def ")
100
100
  # m = WalrusLang::Parser.parse("abc; {{ 'foo{{1+2}}' * bar }} def {{ 4 * 4 }}; def")
101
101
  # # m = TemplateLang.parse("a{{b{{c}}d}}e{{f}}g{{h{{i{{j{{k{{l}}m{{n}}o}}p}}}}}}")
102
- # # puts m.dump
103
102
  # puts m.render(binding)
104
103
 
105
104
  # puts("abc {{ 1 + 2 }} def".mustache)
data/opswalrus.gemspec CHANGED
@@ -32,7 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ["lib"]
33
33
 
34
34
  # gem dependencies
35
- spec.add_dependency "amazing_print", "~> 1.5"
36
35
  spec.add_dependency "binding_of_caller", "~> 1.0"
37
36
  spec.add_dependency "citrus", "~> 3.0"
38
37
  spec.add_dependency "gli", "~> 2.21"
@@ -20,13 +20,19 @@ Vagrant.configure("2") do |config|
20
20
  # Enable provisioning with a shell script. Additional provisioners such as
21
21
  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
22
22
  # documentation for more information about their specific syntax and use.
23
- config.vm.provision "shell", inline: <<-SHELL
24
- sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
25
- sudo systemctl restart sshd
23
+ config.vm.provision "shell" do |s|
24
+ ssh_pub_key = File.readlines("#{Dir.home}/.ssh/id_ops.pub").first.strip
25
+ s.inline = <<-SHELL
26
+ echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
27
+ echo #{ssh_pub_key} >> /root/.ssh/authorized_keys
26
28
 
27
- # change vagrant user to require sudo password
28
- sudo sed -i 's/vagrant ALL=(ALL) NOPASSWD:ALL/vagrant ALL=(ALL:ALL) ALL/g' /etc/sudoers.d/vagrant
29
+ sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
30
+ sudo systemctl restart sshd
29
31
 
30
- # sudo sh -c 'echo root:foo | chpasswd'
31
- SHELL
32
+ # change vagrant user to require sudo password
33
+ sudo sed -i 's/vagrant ALL=(ALL) NOPASSWD:ALL/vagrant ALL=(ALL:ALL) ALL/g' /etc/sudoers.d/vagrant
34
+
35
+ # sudo sh -c 'echo root:foo | chpasswd'
36
+ SHELL
37
+ end
32
38
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opswalrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.39
4
+ version: 1.0.40
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-06 00:00:00.000000000 Z
11
+ date: 2023-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: amazing_print
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.5'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.5'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: binding_of_caller
29
15
  requirement: !ruby/object:Gem::Requirement