foreman_maintain 0.2.7 → 0.2.8

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
  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