foreman_maintain 0.2.7 → 0.2.8

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
  SHA1:
3
- metadata.gz: 3f61cb7b275e9978bc032513744950f822778872
4
- data.tar.gz: f7614599245417a2fe6701e1216e234104743e63
3
+ metadata.gz: 3a34b76c9a33401d8fdcdd6060d927ec7524bbe4
4
+ data.tar.gz: 650f353493cb6d4ba3f8f74645fd214e7eb3829f
5
5
  SHA512:
6
- metadata.gz: beb2a3862349655e2de9f31bfc069693304adae28ddc693fa3c74d2fece3412139a5e256bacbdf43eda8cdd19edc1047707e607c015308dc37002b0d88710078
7
- data.tar.gz: 262695d71ed612c0eba941c14db87559e86c9057b03f63c33b4f24c1795dd7fe50bd4cc477aa32144a95a9f5610d2d45350c02bc8901cbdd857ce3fd4cc4967d
6
+ metadata.gz: 3c5775e4e063a09e46511cf7ddc8803ccefb3ab512d7b7c7c6e74d4d9164b27437715474a9100221dd82bc3f80425190c9ee9e84d52bfb771f282fef11a4879a
7
+ data.tar.gz: 5a34a85f37bc1295a3ec1591b71e8d3782a839b3de2c2433bb43b09634d112137d59aa1fb4c94f644f4cabf8b349a83e4cc232b2392291dfc88c81a113458b12
data/README.md CHANGED
@@ -385,6 +385,43 @@ foreman-maintain console
385
385
  foreman-maintain config
386
386
  ```
387
387
 
388
+ ## Bash completion
389
+
390
+ The completion offers suggestion of possible command-line subcommands and their options
391
+ as usual. It can also suggest values for options and params where file
392
+ or directory path is expected.
393
+
394
+ Bash completion is automatically installed by RPM. To use it for development setup
395
+ `cp ./config/foreman-maintain.completion /etc/bash_completion.d/foreman-maintain`
396
+ and load it to the current shell `source /etc/bash_completion.d/foreman-maintain`.
397
+ Make sure the `$PWD/bin` is in `PATH` or there is full path to `foreman-maintain-complete`
398
+ executable specified in `/etc/bash_completion.d/foreman-maintain`.
399
+
400
+ Bash completion for foreman-maintain needs pre-built cache that holds description of
401
+ all subcommands and its parameters. The cache is located by default in
402
+ `~/.cache/foreman_maintain_completion.yml`. The location can be changed in foreman-maintain's
403
+ config file. The cache can be built manually with
404
+ `foreman-maintain advanced prebuild-bash-completion` or is built automatically when
405
+ completion is used and the cache is missing (this may cause slight delay). The cache expires
406
+ after installer scenario answer file changed (it indicates that the features on the instance
407
+ may have changed which has impact on foreman-maintain CLI options and subcommands).
408
+
409
+ #### Available value types
410
+
411
+ Completion of values is dependent on CLI option and prameter settings, e.g.:
412
+
413
+ ```ruby
414
+ parameter 'BACKUP_DIR', 'Path to backup dir', :completion => { :type => :directory }
415
+ ```
416
+
417
+ Possible options for the `:completion` attribute are:
418
+ - `{ :type => :flag }` option has no value, default for flags
419
+ - `{ :type => :value }` option has value of unknown type, no suggestions for the value, default
420
+ - `{ :type => :directory }` value is directory, suggestions follow directory structure
421
+ - `{ :type => :file, :filter => '\.txt$' }` value is file, suggestions follow directory structure,
422
+ optional `:filter` is regexp to filter the results.
423
+
424
+
388
425
  ## How to contribute?
389
426
 
390
427
  Generally, follow the [Foreman guidelines](https://theforeman.org/contribute.html). For code-related contributions, fork this project and send a pull request with all changes. Some things to keep in mind:
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ require 'English'
3
+ project_root = File.expand_path('../..', __FILE__)
4
+ $LOAD_PATH.unshift(File.join(project_root, 'lib'))
5
+ CONFIG_FILE = '/etc/foreman-maintain/foreman_maintain.yml'.freeze
6
+ system('which foreman_maintain > /dev/null 2>&1')
7
+ found = $CHILD_STATUS.success?
8
+ FOREMAN_MAINTAIN = found ? 'foreman-maintain' : File.join(project_root, 'bin/foreman-maintain')
9
+
10
+ require 'yaml'
11
+ require 'foreman_maintain/utils/bash'
12
+
13
+ # rubocop:disable Lint/RescueWithoutErrorClass, Lint/HandleExceptions
14
+ def cache_file(config_file)
15
+ config = YAML.load(File.open(config_file))
16
+ config[:completion_cache_file]
17
+ rescue
18
+ end
19
+ # rubocop:enable Lint/RescueWithoutErrorClass, Lint/HandleExceptions
20
+
21
+ config_file = if File.exist?(CONFIG_FILE)
22
+ CONFIG_FILE
23
+ else
24
+ File.join(project_root, 'config/foreman_maintain.yml')
25
+ end
26
+ completion_cache_file = cache_file(config_file) || '~/.cache/foreman_maintain_completion.yml'
27
+ completion_cache_file = File.expand_path(completion_cache_file)
28
+
29
+ # build the cache if it does not exist
30
+ `#{FOREMAN_MAINTAIN} advanced prebuild-bash-completion` unless File.exist?(completion_cache_file)
31
+
32
+ dict = ForemanMaintain::Utils::Bash::Completion.load_description(completion_cache_file)
33
+
34
+ # regenerate and reload cache if it expired
35
+ sha1sum = `sha1sum #{dict[:expire][:file]}`
36
+ if sha1sum.strip != dict[:expire][:sha1sum].strip
37
+ `#{FOREMAN_MAINTAIN} advanced prebuild-bash-completion`
38
+ dict = ForemanMaintain::Utils::Bash::Completion.load_description(completion_cache_file)
39
+ end
40
+
41
+ comp_line = ENV['COMP_LINE'] || ''
42
+ comp_args = comp_line.split(' ', 2).last || ''
43
+
44
+ result = ForemanMaintain::Utils::Bash::Completion.new(dict).complete(comp_args)
45
+
46
+ puts result.join("\n")
@@ -0,0 +1,5 @@
1
+ #
2
+ # Foreman Maintain bash completion script
3
+ #
4
+
5
+ complete -C foreman-maintain-complete -o nospace foreman-maintain
@@ -0,0 +1,21 @@
1
+ # Directory where the logs are stored.
2
+ # The default file is named as /log/foreman_maintain.log
3
+ :log_dir: 'log'
4
+
5
+ # Logger levels: mention one of debug, info, warning, error, fatal
6
+ :log_level: 'error'
7
+
8
+ # Mention log file size in KB. Default set to 10000KB.
9
+ # :log_file_size: 10000
10
+
11
+ # Mention definitions directories. Default
12
+ # :definitions_dirs:
13
+
14
+ # Mention file path to store data
15
+ # :storage_file: 'data.yml'
16
+
17
+ # Mention directory to store whole backup data
18
+ :backup_dir: '/tmp/foreman-maintain'
19
+
20
+ # Mention path where foreman-proxy certificates stored on filesystem
21
+ # :foreman_proxy_cert_path: '/etc/foreman'
@@ -23,3 +23,5 @@
23
23
  # Mention directory path to store candlepin db backups
24
24
  # :db_backup_dir: '/var/lib/foreman-maintain/db-backups'
25
25
 
26
+ # Location of cache for bash completion
27
+ :completion_cache_file: '~/.cache/foreman_maintain_completion.yml'
@@ -22,3 +22,6 @@
22
22
 
23
23
  # Mention directory path to store candlepin db backups
24
24
  # :db_backup_dir: '/var/lib/foreman-maintain/db-backups'
25
+
26
+ # Location of cache for bash completion
27
+ :completion_cache_file: '~/.cache/foreman_maintain_completion.yml'
@@ -0,0 +1,3 @@
1
+ :foreman:
2
+ :username:
3
+ :password:
@@ -0,0 +1,37 @@
1
+ ---
2
+ #
3
+ # Trivial Passenger memory monitor. By default it is executed from cron every
4
+ # five minutes and it kills one process that exceeds the RSS memory threashold
5
+ # configured.
6
+ #
7
+
8
+ # Set to 'false' to completely disable this script.
9
+ :ENABLED: true
10
+
11
+ # RSS memory threashold to recycle processes (in kB).
12
+ :MAX_PRIV_RSS_MEMORY: 2_000_000
13
+
14
+ # Controls amount of processes killed during one run. This number should be
15
+ # smaller by one or two than maximum allowed amount of processes by passenger
16
+ # (defaults to 6) so there is at least one process left.
17
+ :MAX_TERMINATION: 4
18
+
19
+ # Kill processes which do not terminate gracefully using SIGKILL after
20
+ # GRACEFUL_SHUTDOWN_SLEEP period.
21
+ :KILL_BUSY: true
22
+
23
+ # Amount of seconds to wait for graceful shutdown (SIGTERM) until a process
24
+ # kill (SIGKILL) is sent. Must be lower than 15 minutes (900 seconds). This
25
+ # gives Passenger some extra time for respawning application before another
26
+ # process is terminated.
27
+ :GRACEFUL_SHUTDOWN_SLEEP: 90
28
+
29
+ # Print 'passenger-status' and 'ps' output before termination to get some extra
30
+ # information via email from cron. Only printed when a kill is performed.
31
+ :SEND_STATUS: true
32
+
33
+ # Print verbose information "Process terminating" or "Process killed".
34
+ :VERBOSE: true
35
+
36
+ # Print extra debugging information.
37
+ :DEBUG: false
@@ -38,7 +38,7 @@ class Features::Downstream < ForemanMaintain::Feature
38
38
  end
39
39
 
40
40
  def absent_repos(version)
41
- all_repo_lines = execute(%(LANG=en_US.utf-8 subscription-manager repos --list | ) +
41
+ all_repo_lines = execute(%(LANG=en_US.utf-8 subscription-manager repos --list 2>&1 | ) +
42
42
  %(grep '^Repo ID:')).split("\n")
43
43
  all_repos = all_repo_lines.map { |line| line.split(/\s+/).last }
44
44
  repos_required = rh_repos(version)
@@ -20,13 +20,21 @@ class Features::Installer < ForemanMaintain::Feature
20
20
  end
21
21
 
22
22
  def answers
23
+ load_answers(configuration)
24
+ end
25
+
26
+ def configuration
27
+ YAML.load_file(config_file)
28
+ end
29
+
30
+ def config_file
23
31
  case @installer_type
24
32
  when :scenarios
25
- last_scenario_answers
33
+ last_scenario_config
26
34
  when :legacy_katello
27
- load_answers(File.join(config_directory, 'katello-installer.yaml'))
35
+ File.join(config_directory, 'katello-installer.yaml')
28
36
  when :legacy_capsule
29
- load_answers(File.join(config_directory, 'capsule-installer.yaml'))
37
+ File.join(config_directory, 'capsule-installer.yaml')
30
38
  end
31
39
  end
32
40
 
@@ -87,19 +95,10 @@ class Features::Installer < ForemanMaintain::Feature
87
95
 
88
96
  private
89
97
 
90
- def load_answers(config_file)
91
- config = YAML.load_file(config_file)
98
+ def load_answers(config)
92
99
  YAML.load_file(config[:answer_file])
93
100
  end
94
101
 
95
- def scenario_answers(scenario)
96
- load_answers(File.join(config_directory, "scenarios.d/#{scenario}.yaml"))
97
- end
98
-
99
- def last_scenario_answers
100
- scenario_answers(last_scenario)
101
- end
102
-
103
102
  def last_scenario_config
104
103
  Pathname.new(File.join(config_directory, 'scenarios.d/last_scenario.yaml')).realpath.to_s
105
104
  end
@@ -0,0 +1,20 @@
1
+ require 'fileutils'
2
+
3
+ module ForemanMaintain
4
+ module Cli
5
+ class PrebuildBashCompletionCommand < Base
6
+ include ForemanMaintain::Concerns::SystemHelpers
7
+ def execute
8
+ comp_map = ForemanMaintain::Cli::MainCommand.completion_map
9
+ answers = feature(:installer).configuration[:answer_file]
10
+ comp_map[:expire] = {
11
+ :file => answers,
12
+ :sha1sum => execute!("sha1sum #{answers}")
13
+ }
14
+ cache_dir = File.dirname(ForemanMaintain.config.completion_cache_file)
15
+ FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
16
+ File.write(ForemanMaintain.config.completion_cache_file, comp_map.to_yaml)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,9 +1,13 @@
1
1
  require 'foreman_maintain/cli/advanced/procedure_command'
2
+ require 'foreman_maintain/cli/advanced/prebuild_bash_completion'
2
3
 
3
4
  module ForemanMaintain
4
5
  module Cli
5
6
  class AdvancedCommand < Base
6
7
  subcommand 'procedure', 'Run maintain procedures manually', ProcedureCommand
8
+ subcommand 'prebuild-bash-completion',
9
+ 'Prepare map of options and subcommands for Bash completion',
10
+ PrebuildBashCompletionCommand
7
11
  end
8
12
  end
9
13
  end
@@ -33,6 +33,7 @@ module ForemanMaintain
33
33
  def common_backup_options
34
34
  # TODO: BACKUP_DIR in f-m config - should be default?
35
35
  parameter 'BACKUP_DIR', 'Path to backup dir',
36
+ :completion => { :type => :directory },
36
37
  :attribute_name => :backup_root_dir do |dir|
37
38
  File.expand_path(dir)
38
39
  end
@@ -44,7 +45,8 @@ module ForemanMaintain
44
45
  self.class.valid_tape_size(size)
45
46
  end
46
47
  option ['-i', '--incremental'], 'PREVIOUS_BACKUP_DIR',
47
- 'Backup changes since previous backup' do |dir|
48
+ 'Backup changes since previous backup',
49
+ :completion => { :type => :directory } do |dir|
48
50
  unless File.directory?(dir)
49
51
  raise ArgumentError, "Previous backup directory does not exist: #{dir}"
50
52
  end
@@ -67,8 +67,33 @@ module ForemanMaintain
67
67
  collection.inject([]) { |array, item| array.concat(item.tags).uniq }.sort_by(&:to_s)
68
68
  end
69
69
 
70
+ def self.completion_map
71
+ completion = {}
72
+ # collect options
73
+ recognised_options.each do |opt|
74
+ opt.switches.each do |switch|
75
+ completion[switch] = completion_types.fetch(switch, {})
76
+ end
77
+ end
78
+ # collect subcommands recursively
79
+ recognised_subcommands.each do |cmd|
80
+ completion[cmd.names.first] = cmd.subcommand_class.completion_map
81
+ end
82
+ # collect params
83
+ completion[:params] = completion_types[:params] unless completion_types[:params].empty?
84
+ completion
85
+ end
86
+
87
+ def self.completion_types
88
+ @completion_types ||= { :params => [] }
89
+ end
90
+
70
91
  def self.option(switches, type, description, opts = {}, &block)
71
92
  multivalued = opts.delete(:multivalued)
93
+ completion_type = opts.delete(:completion)
94
+ completion_type = { :type => :flag } if completion_type.nil? && type == :flag
95
+ completion_type ||= { :type => :value }
96
+ [switches].flatten(1).each { |s| completion_types[s] = completion_type }
72
97
  description += ' (comma-separated list)' if multivalued
73
98
  super(switches, type, description, opts) do |value|
74
99
  value = CSVParser.new.parse(value) if multivalued
@@ -77,6 +102,15 @@ module ForemanMaintain
77
102
  end
78
103
  end
79
104
 
105
+ def self.parameter(name, description, opts = {}, &block)
106
+ unless [:subcommand_name, :subcommand_arguments].include?(opts[:attribute_name])
107
+ completion_type = opts.delete(:completion)
108
+ completion_type ||= { :type => :value }
109
+ completion_types[:params] << completion_type
110
+ end
111
+ super(name, description, opts, &block)
112
+ end
113
+
80
114
  def self.label_option
81
115
  option '--label', 'label',
82
116
  'Limit only for a specific label. ' \
@@ -3,10 +3,10 @@ module ForemanMaintain
3
3
  class RestoreCommand < Base
4
4
  interactive_option
5
5
  parameter 'BACKUP_DIR', 'Path to backup directory to restore',
6
- :attribute_name => :backup_dir
6
+ :attribute_name => :backup_dir, :completion => { :type => :directory }
7
7
 
8
8
  option ['-i', '--incremental'], :flag, 'Restore an incremental backup',
9
- :attribute_name => :incremental
9
+ :attribute_name => :incremental, :completion => { :type => :directory }
10
10
 
11
11
  def execute
12
12
  scenario = Scenarios::Restore.new(
@@ -4,7 +4,7 @@ module ForemanMaintain
4
4
  attr_accessor :pre_setup_log_messages,
5
5
  :config_file, :definitions_dirs, :log_level, :log_dir, :log_file_size,
6
6
  :storage_file, :backup_dir, :foreman_proxy_cert_path,
7
- :db_backup_dir
7
+ :db_backup_dir, :completion_cache_file
8
8
 
9
9
  def initialize(options)
10
10
  @pre_setup_log_messages = []
@@ -15,6 +15,9 @@ module ForemanMaintain
15
15
  load_log_configs
16
16
  load_backup_dir_paths
17
17
  @foreman_proxy_cert_path = @options.fetch(:foreman_proxy_cert_path, '/etc/foreman')
18
+ @completion_cache_file = File.expand_path(
19
+ @options.fetch(:completion_cache_file, '~/.cache/foreman_maintain_completion.yml')
20
+ )
18
21
  end
19
22
 
20
23
  private
@@ -0,0 +1,123 @@
1
+ require 'yaml'
2
+
3
+ module ForemanMaintain
4
+ module Utils
5
+ module Bash
6
+ class Completion
7
+ def initialize(dict)
8
+ @dict = dict
9
+ end
10
+
11
+ def complete(line)
12
+ @complete_line = line.end_with?(' ')
13
+ full_path = line.split(' ')
14
+ complete_path = @complete_line ? full_path : full_path[0..-2]
15
+ dict, path = traverse_tree(@dict, complete_path)
16
+
17
+ return [] unless path.empty? # lost during traversing
18
+
19
+ partial = @complete_line ? '' : full_path.last
20
+ finish_word(dict, partial)
21
+ end
22
+
23
+ def self.load_description(path)
24
+ YAML.load(File.open(path))
25
+ rescue Errno::ENOENT
26
+ {}
27
+ end
28
+
29
+ private
30
+
31
+ def finish_word(dict, incomplete)
32
+ finish_option_value(dict, incomplete) ||
33
+ (finish_option_or_subcommand(dict, incomplete) + finish_param(dict, incomplete))
34
+ end
35
+
36
+ def finish_option_or_subcommand(dict, incomplete)
37
+ dict.keys.select { |k| k.is_a?(String) && k =~ /^#{incomplete}/ }.map { |k| k + ' ' }
38
+ end
39
+
40
+ def complete_value(value_description, partial, is_param)
41
+ case value_description[:type]
42
+ when :value
43
+ if !partial.empty?
44
+ []
45
+ elsif is_param
46
+ ['--->', 'Add parameter']
47
+ else
48
+ ['--->', 'Add option <value>']
49
+ end
50
+ when :directory
51
+ directories(partial)
52
+ when :file
53
+ files(partial, value_description)
54
+ end
55
+ end
56
+
57
+ def finish_param(dict, incomplete)
58
+ if dict[:params] && !dict[:params].empty?
59
+ complete_value(dict[:params].first, incomplete, true)
60
+ else
61
+ []
62
+ end
63
+ end
64
+
65
+ def finish_option_value(dict, incomplete)
66
+ complete_value(dict, incomplete, false) if dict.key?(:type)
67
+ end
68
+
69
+ def traverse_tree(dict, path)
70
+ return [dict, []] if path.nil? || path.empty?
71
+ result = if dict.key?(path.first)
72
+ if path.first.start_with?('-')
73
+ parse_option(dict, path)
74
+ else
75
+ parse_subcommand(dict, path)
76
+ end
77
+ elsif dict[:params]
78
+ # traverse params one by one
79
+ parse_params(dict, path)
80
+ else
81
+ # not found
82
+ [{}, path]
83
+ end
84
+ result
85
+ end
86
+
87
+ def parse_params(dict, path)
88
+ traverse_tree({ :params => dict[:params][1..-1] }, path[1..-1])
89
+ end
90
+
91
+ def parse_subcommand(dict, path)
92
+ traverse_tree(dict[path.first], path[1..-1])
93
+ end
94
+
95
+ def parse_option(dict, path)
96
+ if dict[path.first][:type] == :flag # flag
97
+ traverse_tree(dict, path[1..-1])
98
+ elsif path.length >= 2 # option with value
99
+ traverse_tree(dict, path[2..-1])
100
+ else # option with value missing
101
+ [dict[path.first], path[1..-1]]
102
+ end
103
+ end
104
+
105
+ def directories(partial = '')
106
+ dirs = []
107
+ dirs += Dir.glob("#{partial}*").select { |f| File.directory?(f) }
108
+ dirs = dirs.map { |d| d + '/' } if dirs.length == 1
109
+ dirs
110
+ end
111
+
112
+ def files(partial = '', opts = {})
113
+ filter = opts.fetch(:filter, '.*')
114
+ file_names = []
115
+ file_names += Dir.glob("#{partial}*").select do |f|
116
+ File.directory?(f) || f =~ /#{filter}/
117
+ end
118
+ file_names.map { |f| File.directory?(f) ? f + '/' : f + ' ' }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,5 +1,6 @@
1
1
  require 'foreman_maintain/utils/command_runner'
2
2
  require 'foreman_maintain/utils/disk'
3
+ require 'foreman_maintain/utils/bash'
3
4
  require 'foreman_maintain/utils/hash_tools'
4
5
  require 'foreman_maintain/utils/curl_response'
5
6
  require 'foreman_maintain/utils/mongo_core'
@@ -1,3 +1,3 @@
1
1
  module ForemanMaintain
2
- VERSION = '0.2.7'.freeze
2
+ VERSION = '0.2.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_maintain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-15 00:00:00.000000000 Z
11
+ date: 2018-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -100,6 +100,7 @@ email: inecas@redhat.com
100
100
  executables:
101
101
  - foreman-maintain
102
102
  - passenger-recycler
103
+ - foreman-maintain-complete
103
104
  - foreman-maintain-rotate-tar
104
105
  extensions: []
105
106
  extra_rdoc_files:
@@ -109,10 +110,15 @@ files:
109
110
  - LICENSE
110
111
  - README.md
111
112
  - bin/foreman-maintain
113
+ - bin/foreman-maintain-complete
112
114
  - bin/foreman-maintain-rotate-tar
113
115
  - bin/passenger-recycler
116
+ - config/foreman-maintain.completion
117
+ - config/foreman_maintain.yml
114
118
  - config/foreman_maintain.yml.example
115
119
  - config/foreman_maintain.yml.packaging
120
+ - config/hammer.yml.example
121
+ - config/passenger-recycler.yaml
116
122
  - definitions/checks/backup/certs_tar_exist.rb
117
123
  - definitions/checks/backup/directory_ready.rb
118
124
  - definitions/checks/candlepin/db_up.rb
@@ -233,6 +239,7 @@ files:
233
239
  - lib/foreman_maintain.rb
234
240
  - lib/foreman_maintain/check.rb
235
241
  - lib/foreman_maintain/cli.rb
242
+ - lib/foreman_maintain/cli/advanced/prebuild_bash_completion.rb
236
243
  - lib/foreman_maintain/cli/advanced/procedure/abstract_by_tag_command.rb
237
244
  - lib/foreman_maintain/cli/advanced/procedure/abstract_procedure_command.rb
238
245
  - lib/foreman_maintain/cli/advanced/procedure/by_tag_command.rb
@@ -275,6 +282,7 @@ files:
275
282
  - lib/foreman_maintain/upgrade_runner.rb
276
283
  - lib/foreman_maintain/utils.rb
277
284
  - lib/foreman_maintain/utils/backup.rb
285
+ - lib/foreman_maintain/utils/bash.rb
278
286
  - lib/foreman_maintain/utils/command_runner.rb
279
287
  - lib/foreman_maintain/utils/curl_response.rb
280
288
  - lib/foreman_maintain/utils/disk.rb
@@ -307,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
315
  version: '0'
308
316
  requirements: []
309
317
  rubyforge_project:
310
- rubygems_version: 2.6.12
318
+ rubygems_version: 2.6.14.1
311
319
  signing_key:
312
320
  specification_version: 4
313
321
  summary: Foreman maintenance tool belt