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 +4 -4
- data/README.md +37 -0
- data/bin/foreman-maintain-complete +46 -0
- data/config/foreman-maintain.completion +5 -0
- data/config/foreman_maintain.yml +21 -0
- data/config/foreman_maintain.yml.example +2 -0
- data/config/foreman_maintain.yml.packaging +3 -0
- data/config/hammer.yml.example +3 -0
- data/config/passenger-recycler.yaml +37 -0
- data/definitions/features/downstream.rb +1 -1
- data/definitions/features/installer.rb +12 -13
- data/lib/foreman_maintain/cli/advanced/prebuild_bash_completion.rb +20 -0
- data/lib/foreman_maintain/cli/advanced_command.rb +4 -0
- data/lib/foreman_maintain/cli/backup_command.rb +3 -1
- data/lib/foreman_maintain/cli/base.rb +34 -0
- data/lib/foreman_maintain/cli/restore_command.rb +2 -2
- data/lib/foreman_maintain/config.rb +4 -1
- data/lib/foreman_maintain/utils/bash.rb +123 -0
- data/lib/foreman_maintain/utils.rb +1 -0
- data/lib/foreman_maintain/version.rb +1 -1
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a34b76c9a33401d8fdcdd6060d927ec7524bbe4
|
4
|
+
data.tar.gz: 650f353493cb6d4ba3f8f74645fd214e7eb3829f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,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'
|
@@ -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
|
-
|
33
|
+
last_scenario_config
|
26
34
|
when :legacy_katello
|
27
|
-
|
35
|
+
File.join(config_directory, 'katello-installer.yaml')
|
28
36
|
when :legacy_capsule
|
29
|
-
|
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(
|
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'
|
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
|
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.
|
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-
|
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.
|
318
|
+
rubygems_version: 2.6.14.1
|
311
319
|
signing_key:
|
312
320
|
specification_version: 4
|
313
321
|
summary: Foreman maintenance tool belt
|