opswalrus 1.0.39 → 1.0.41

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: 413ca26075395f1e533a83af05aae8522f66fb91b96de13d8932f5856053222d
4
- data.tar.gz: cf99aa4a8e71dba2a36129ed3ca2cb51b603d106fd240a0d1d39784e53e6806c
3
+ metadata.gz: 1e253e6b949d98e3d7deea0044949e94f5e308a2258412cc8667c7af2fe059f9
4
+ data.tar.gz: 91c12649f126a65c780111fde50cac4d9be674a32ea85d7771df681741ce1ef7
5
5
  SHA512:
6
- metadata.gz: 5ba6764a3018cc959a075b9616d14116ae28c565a53f557864fb6d9ce1b922d75439e79b1563fedd7a4a5cd2a17277243ee8b1d47d5f82c30f6898d08b4088bc
7
- data.tar.gz: f8985876bbc10366839f871818a50d4578728d63f5234ec13479a54801b5771fc8f5e7f9a5c3328c58a508997cd5e12b581b45de1aae759e1a6a71dedeb33118
6
+ metadata.gz: 694d15c5c835df26743fc1ebcae8e8f0a6a517aad301b73780298590f9c3b3834c731e12363321eff5c7c04c14ed8e9206869d6d8a7c1a32e767eb1a093a6505
7
+ data.tar.gz: 57a5a9fe9f55cab60fb9fbb104b5e6b7c588ee0308c06ed63ac90996328a8f515e9512a6d746a5d943652fceea2804c6ed40e4063f7fe96863d4c762785cc404
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.41)
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"
@@ -26,8 +27,8 @@ if [ -x $RTX ]; then
26
27
 
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
- # gem install opswalrus
30
- $GEM_CMD install opswalrus
30
+ gem 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.41"
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.41
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