cmdb 2.6.2 → 3.0.0rc1
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/.dockerignore +7 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +71 -34
- data/Gemfile +4 -3
- data/Gemfile.lock +6 -19
- data/LICENSE +25 -0
- data/README.md +138 -166
- data/Rakefile +13 -0
- data/cmdb.gemspec +1 -3
- data/docker-compose.yml +15 -0
- data/exe/cmdb +36 -9
- data/lib/cmdb/commands/help.rb +21 -66
- data/lib/cmdb/commands/shell.rb +165 -0
- data/lib/cmdb/commands/shim.rb +13 -128
- data/lib/cmdb/commands.rb +1 -0
- data/lib/cmdb/interface.rb +51 -59
- data/lib/cmdb/shell/dsl.rb +73 -0
- data/lib/cmdb/shell/printer.rb +115 -0
- data/lib/cmdb/shell/text.rb +65 -0
- data/lib/cmdb/shell.rb +8 -0
- data/lib/cmdb/source/consul.rb +90 -0
- data/lib/cmdb/{file_source.rb → source/file.rb} +15 -34
- data/lib/cmdb/source/memory.rb +39 -0
- data/lib/cmdb/source/network.rb +104 -0
- data/lib/cmdb/source.rb +94 -0
- data/lib/cmdb/version.rb +1 -1
- data/lib/cmdb.rb +26 -17
- metadata +18 -36
- data/TODO.md +0 -3
- data/lib/cmdb/consul_source.rb +0 -83
data/docker-compose.yml
ADDED
data/exe/cmdb
CHANGED
@@ -20,37 +20,64 @@ CMDB::Commands.constants.each do |konst|
|
|
20
20
|
commands[name] = CMDB::Commands.const_get(konst.to_sym)
|
21
21
|
end
|
22
22
|
|
23
|
-
# Use a Trollop parser for help/banner display, but do not actually parse
|
24
|
-
# anything just yet.
|
25
23
|
command_list = commands.keys - ['help']
|
26
24
|
command_info = command_list.map { |c| " * #{c}" }.join("\n")
|
25
|
+
|
26
|
+
# Use a Trollop parser for help/banner display, but do not actually parse
|
27
|
+
# anything just yet.
|
27
28
|
p = Trollop::Parser.new do
|
28
29
|
version "cmdb #{gemspec_version} (c) 2013-2014 RightScale, Inc."
|
29
30
|
banner <<-EOS
|
30
31
|
A command-line interface for configuration management.
|
31
32
|
|
32
33
|
Usage:
|
33
|
-
cmdb <command> [options]
|
34
|
+
cmdb [options] <command> [command-options]
|
34
35
|
|
35
36
|
Where <command> is one of:
|
36
37
|
#{command_info}
|
37
38
|
|
38
|
-
To get help on a command:
|
39
|
-
cmdb help command
|
39
|
+
To get help on a specific command and its options:
|
40
|
+
cmdb help <command>
|
41
|
+
|
42
|
+
Common options that apply to all commands:
|
40
43
|
EOS
|
41
44
|
|
45
|
+
opt :source,
|
46
|
+
"Source of CMDB inputs e.g. file:///foo.yml or consul://localhost",
|
47
|
+
type: :string,
|
48
|
+
multi: true
|
49
|
+
|
50
|
+
opt :quiet,
|
51
|
+
"Suppress unnecessary output",
|
52
|
+
default: false
|
53
|
+
|
42
54
|
stop_on commands.keys
|
43
55
|
end
|
44
56
|
|
45
57
|
Trollop.with_standard_exception_handling p do
|
46
58
|
raise Trollop::HelpNeeded if ARGV.empty?
|
47
|
-
|
59
|
+
|
60
|
+
# Apply global options
|
61
|
+
options = p.parse ARGV
|
62
|
+
CMDB.log.level = Logger::FATAL if options[:quiet]
|
63
|
+
|
64
|
+
if options[:source].empty?
|
65
|
+
sources = CMDB::Source.detect
|
66
|
+
else
|
67
|
+
sources = options[:source].map do |source|
|
68
|
+
CMDB::Source.create(source)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
interface = CMDB::Interface.new(*sources)
|
73
|
+
|
74
|
+
# Identify the subcommand and run it (or print help).
|
75
|
+
raise Trollop::HelpNeeded if ARGV.empty?
|
48
76
|
cmd = ARGV.shift
|
49
77
|
klass = commands[cmd]
|
50
|
-
|
51
78
|
if klass
|
52
|
-
klass.create.run
|
79
|
+
klass.create(interface).run
|
53
80
|
else
|
54
|
-
|
81
|
+
CMDB.log.fatal "Unrecognized command '#{cmd}'; try 'cmdb --help'"
|
55
82
|
end
|
56
83
|
end
|
data/lib/cmdb/commands/help.rb
CHANGED
@@ -1,77 +1,32 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'logger'
|
3
|
-
require 'listen'
|
4
2
|
|
5
3
|
module CMDB::Commands
|
6
4
|
class Help
|
7
|
-
def self.create
|
8
|
-
|
9
|
-
|
10
|
-
The 'shim' command adapts your applications for use with CMDB without coupling them to
|
11
|
-
the CMDB RubyGem (or forcing you to write your applications in Ruby). It works by
|
12
|
-
manipulating the environment or filesystem to make CMDB inputs visible, then invoking
|
13
|
-
your app.
|
14
|
-
|
15
|
-
To use the shim with apps that read configuration from the filesystem, use the --dir
|
16
|
-
option to tell the shim where to rewrite configuration files. It will look for tokens
|
17
|
-
in JSON or YML that look like <<cmdb.key.name>> and replace them with the value of
|
18
|
-
the specified key.
|
19
|
-
|
20
|
-
To use the shim with 12-factor apps, use the --env option to tell the shim to load
|
21
|
-
every CMDB key into the environment. When using --env, the prefix of each key is
|
22
|
-
omitted from the environment variable name, e.g. "common.database.host" is
|
23
|
-
represented as DATABASE_HOST.
|
24
|
-
|
25
|
-
To support "development mode" and reload your app whenever its files change on disk,
|
26
|
-
use the --reload option and specify the name of a CMDB key that will enable this
|
27
|
-
behavior.
|
28
|
-
|
29
|
-
Usage:
|
30
|
-
cmdb shim [options] -- <command_to_exec> [options_for_command]
|
31
|
-
|
32
|
-
Where [options] are selected from:
|
33
|
-
EOS
|
34
|
-
opt :dir,
|
35
|
-
'Directory to scan for key-replacement tokens in data files',
|
36
|
-
type: :string
|
37
|
-
opt :consul_url,
|
38
|
-
'The URL for talking to consul',
|
39
|
-
type: :string
|
40
|
-
opt :consul_prefix,
|
41
|
-
'The prefix to use when getting keys from consul, can be specified more than once',
|
42
|
-
type: :string,
|
43
|
-
multi: true
|
44
|
-
opt :keys,
|
45
|
-
'Override search path(s) for CMDB key files',
|
46
|
-
type: :strings
|
47
|
-
opt :pretend,
|
48
|
-
'Check for errors, but do not actually launch the app or rewrite files',
|
49
|
-
default: false
|
50
|
-
opt :quiet,
|
51
|
-
"Don't print any output",
|
52
|
-
default: false
|
53
|
-
opt :reload,
|
54
|
-
'CMDB key that enables reload-on-edit',
|
55
|
-
type: :string
|
56
|
-
opt :reload_signal,
|
57
|
-
'Signal to send to app server when code is edited',
|
58
|
-
type: :string,
|
59
|
-
default: 'HUP'
|
60
|
-
opt :env,
|
61
|
-
"Add CMDB keys to the app server's process environment",
|
62
|
-
default: false
|
63
|
-
opt :user,
|
64
|
-
'Switch to named user before executing app',
|
65
|
-
type: :string
|
66
|
-
opt :root,
|
67
|
-
'Promote named subkey to the root when it is present in a namespace',
|
68
|
-
type: :string
|
69
|
-
end
|
5
|
+
def self.create(interface)
|
6
|
+
new(interface, ARGV.first)
|
7
|
+
end
|
70
8
|
|
71
|
-
|
9
|
+
def initialize(interface, command)
|
10
|
+
@cmdb = interface
|
11
|
+
@command = command
|
72
12
|
end
|
73
13
|
|
74
14
|
def run
|
15
|
+
if @command.nil? || @command.empty?
|
16
|
+
# Same as "--help"
|
17
|
+
raise Trollop::HelpNeeded
|
18
|
+
end
|
19
|
+
|
20
|
+
# Find the command the user was talking about and print some help
|
21
|
+
konst = CMDB::Commands.constants.detect { |konst| konst.to_s.downcase == @command }
|
22
|
+
if konst
|
23
|
+
klass = CMDB::Commands.const_get(konst)
|
24
|
+
ARGV.clear ; ARGV.push('--help')
|
25
|
+
klass.create(@cmdb)
|
26
|
+
else
|
27
|
+
CMDB.log.fatal "CMDB: Unknown command '#{@command}'; try 'cmdb --help' for a list of commands"
|
28
|
+
exit 1
|
29
|
+
end
|
75
30
|
end
|
76
31
|
end
|
77
32
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CMDB::Commands
|
4
|
+
class Shell
|
5
|
+
# Character that acts as a separator between key components. The standard
|
6
|
+
# notation uses `.` but Shell allow allows `/` for a more filesystem-like
|
7
|
+
# user experience.
|
8
|
+
ALT_SEPARATOR = '/'.freeze
|
9
|
+
|
10
|
+
# Directory navigation shortcuts ('.' and '..')
|
11
|
+
NAVIGATION = /^#{Regexp.escape(CMDB::SEPARATOR + CMDB::SEPARATOR)}?$/.freeze
|
12
|
+
|
13
|
+
def self.create(interface)
|
14
|
+
require 'cmdb/shell'
|
15
|
+
|
16
|
+
options = Trollop.options do
|
17
|
+
banner <<-EOS
|
18
|
+
The 'shell' command enters a Unix-like shell where you can interact with
|
19
|
+
CMDB sources and inspect the value of keys.
|
20
|
+
|
21
|
+
Usage:
|
22
|
+
cmdb shell
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
new(interface)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [CMDB::Interface]
|
30
|
+
attr_reader :cmdb
|
31
|
+
|
32
|
+
# @return [Array] the "present working directory" (i.e. key prefix) for shell commands
|
33
|
+
attr_accessor :pwd
|
34
|
+
|
35
|
+
# @return [Object] esult of the most recent command
|
36
|
+
attr_accessor :_
|
37
|
+
|
38
|
+
# @param [CMDB::Interface] interface
|
39
|
+
def initialize(interface)
|
40
|
+
@cmdb = interface
|
41
|
+
@pwd = []
|
42
|
+
@out = CMDB::Shell::Printer.new
|
43
|
+
end
|
44
|
+
|
45
|
+
# Run the shim.
|
46
|
+
#
|
47
|
+
# @raise [SystemExit] if something goes wrong
|
48
|
+
def run
|
49
|
+
@dsl = CMDB::Shell::DSL.new(self, @out)
|
50
|
+
repl
|
51
|
+
end
|
52
|
+
|
53
|
+
# Given a key name/prefix relative to `pwd`, return the absolute
|
54
|
+
# name/prefix. If `pwd` is empty, just return `subpath`. The subpath
|
55
|
+
# can use either dotted or slash notation, and directory navigation
|
56
|
+
# symbols (`.` and `..`) are applied as expected if the subpath uses
|
57
|
+
# slash notation.
|
58
|
+
#
|
59
|
+
# @return [String] absolute key in dotted notation
|
60
|
+
def expand_path(subpath)
|
61
|
+
pieces = subpath.split(ALT_SEPARATOR)
|
62
|
+
|
63
|
+
if subpath[0] == ALT_SEPARATOR
|
64
|
+
result = []
|
65
|
+
else
|
66
|
+
result = pwd.dup
|
67
|
+
end
|
68
|
+
|
69
|
+
if subpath.include?(ALT_SEPARATOR) || subpath =~ NAVIGATION
|
70
|
+
# filesystem-like subpath
|
71
|
+
# apply Unix-style directory navigation shortcuts
|
72
|
+
pieces.each do |piece|
|
73
|
+
case piece
|
74
|
+
when '..' then result.pop
|
75
|
+
when '.' then nil
|
76
|
+
else result.push(piece)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
result.join(CMDB::SEPARATOR)
|
81
|
+
else
|
82
|
+
# standard dotted notation
|
83
|
+
result += pieces
|
84
|
+
end
|
85
|
+
|
86
|
+
result.join(CMDB::SEPARATOR)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def repl
|
92
|
+
require 'readline'
|
93
|
+
while line = Readline.readline(@out.prompt(self), true)
|
94
|
+
begin
|
95
|
+
line = line.chomp
|
96
|
+
next if line.nil? || line.empty?
|
97
|
+
words = line.split(/\s+/)
|
98
|
+
command, args = words.first.to_sym, words[1..-1]
|
99
|
+
|
100
|
+
run_ruby(command, args) || run_getter(line) || run_setter(line) ||
|
101
|
+
fail(CMDB::BadCommand.new(command))
|
102
|
+
handle_output(self._)
|
103
|
+
rescue => e
|
104
|
+
handle_error(e) || raise
|
105
|
+
end
|
106
|
+
end
|
107
|
+
rescue Interrupt
|
108
|
+
return 0
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Boolean] true if line was handled as a normal command
|
112
|
+
def run_ruby(command, args)
|
113
|
+
self._ = @dsl.__send__(command, *args)
|
114
|
+
true
|
115
|
+
rescue NoMethodError
|
116
|
+
false
|
117
|
+
rescue ArgumentError => e
|
118
|
+
raise CMDB::BadCommand.new(e.message, command)
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Boolean] true if line was handled as a getter
|
122
|
+
def run_getter(key)
|
123
|
+
if value = @dsl.get(key)
|
124
|
+
self._ = value
|
125
|
+
true
|
126
|
+
else
|
127
|
+
false
|
128
|
+
end
|
129
|
+
rescue CMDB::Error
|
130
|
+
false
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [Boolean] true if line was handled as a setter
|
134
|
+
def run_setter(line)
|
135
|
+
key, value = line.strip.split(/\s*=\s*/, 2)
|
136
|
+
return false unless key && value
|
137
|
+
|
138
|
+
value = nil unless value && value.length > 0
|
139
|
+
self._ = @dsl.set(key, value)
|
140
|
+
true
|
141
|
+
rescue CMDB::Error
|
142
|
+
false
|
143
|
+
end
|
144
|
+
|
145
|
+
def handle_output(obj)
|
146
|
+
case obj
|
147
|
+
when Hash
|
148
|
+
@out.keys_values(obj)
|
149
|
+
else
|
150
|
+
@out.value(obj)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @return [Boolean] print message and return true if error is handled; else return false
|
155
|
+
def handle_error(e)
|
156
|
+
case e
|
157
|
+
when CMDB::BadCommand
|
158
|
+
@out.error "#{e.command}: #{e.message}"
|
159
|
+
true
|
160
|
+
else
|
161
|
+
false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/lib/cmdb/commands/shim.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'logger'
|
3
|
-
require 'listen'
|
4
2
|
|
5
3
|
module CMDB::Commands
|
6
4
|
class Shim
|
7
|
-
def self.create
|
5
|
+
def self.create(interface)
|
8
6
|
options = Trollop.options do
|
9
7
|
banner <<-EOS
|
10
8
|
The 'shim' command adapts your applications for use with CMDB without coupling them to
|
@@ -12,7 +10,7 @@ the CMDB RubyGem (or forcing you to write your applications in Ruby). It works b
|
|
12
10
|
manipulating the environment or filesystem to make CMDB inputs visible, then invoking
|
13
11
|
your app.
|
14
12
|
|
15
|
-
To use the shim with apps that read configuration from the filesystem, use the --
|
13
|
+
To use the shim with apps that read configuration from the filesystem, use the --rewrite
|
16
14
|
option to tell the shim where to rewrite configuration files. It will look for tokens
|
17
15
|
in JSON or YML that look like <<cmdb.key.name>> and replace them with the value of
|
18
16
|
the specified key.
|
@@ -22,53 +20,28 @@ every CMDB key into the environment. When using --env, the prefix of each key is
|
|
22
20
|
omitted from the environment variable name, e.g. "common.database.host" is
|
23
21
|
represented as DATABASE_HOST.
|
24
22
|
|
25
|
-
To support "development mode" and reload your app whenever its files change on disk,
|
26
|
-
use the --reload option and specify the name of a CMDB key that will enable this
|
27
|
-
behavior.
|
28
|
-
|
29
23
|
Usage:
|
30
24
|
cmdb shim [options] -- <command_to_exec> [options_for_command]
|
31
25
|
|
32
26
|
Where [options] are selected from:
|
33
27
|
EOS
|
34
|
-
opt :
|
28
|
+
opt :rewrite,
|
35
29
|
'Directory to scan for key-replacement tokens in data files',
|
36
30
|
type: :string
|
37
|
-
opt :consul_url,
|
38
|
-
'The URL for talking to consul',
|
39
|
-
type: :string
|
40
|
-
opt :consul_prefix,
|
41
|
-
'The prefix to use when getting keys from consul, can be specified more than once',
|
42
|
-
type: :string,
|
43
|
-
multi: true
|
44
|
-
opt :keys,
|
45
|
-
'Override search path(s) for CMDB key files',
|
46
|
-
type: :strings
|
47
31
|
opt :pretend,
|
48
32
|
'Check for errors, but do not actually launch the app or rewrite files',
|
49
33
|
default: false
|
50
|
-
opt :quiet,
|
51
|
-
"Don't print any output",
|
52
|
-
default: false
|
53
|
-
opt :reload,
|
54
|
-
'CMDB key that enables reload-on-edit',
|
55
|
-
type: :string
|
56
|
-
opt :reload_signal,
|
57
|
-
'Signal to send to app server when code is edited',
|
58
|
-
type: :string,
|
59
|
-
default: 'HUP'
|
60
34
|
opt :env,
|
61
35
|
"Add CMDB keys to the app server's process environment",
|
62
36
|
default: false
|
63
37
|
opt :user,
|
64
38
|
'Switch to named user before executing app',
|
65
39
|
type: :string
|
66
|
-
opt :root,
|
67
|
-
'Promote named subkey to the root when it is present in a namespace',
|
68
|
-
type: :string
|
69
40
|
end
|
41
|
+
options.delete(:help)
|
70
42
|
|
71
|
-
|
43
|
+
options.delete_if { |k, v| k.to_s =~ /_given$/i }
|
44
|
+
new(interface, ARGV, **options)
|
72
45
|
end
|
73
46
|
|
74
47
|
# Irrevocably change the current user for this Unix process by calling the
|
@@ -90,35 +63,18 @@ Where [options] are selected from:
|
|
90
63
|
|
91
64
|
# Create a Shim.
|
92
65
|
# @param [Array] command collection of string to pass to Kernel#exec; 0th element is the command name
|
93
|
-
|
94
|
-
|
66
|
+
def initialize(interface, command, rewrite:, pretend:, user:)
|
67
|
+
@cmdb = interface
|
95
68
|
@command = command
|
96
|
-
@dir =
|
97
|
-
@
|
98
|
-
@
|
99
|
-
@keys = options[:keys] || []
|
100
|
-
@pretend = options[:pretend]
|
101
|
-
@reload = options[:reload]
|
102
|
-
@signal = options[:reload_signal]
|
103
|
-
@env = options[:env]
|
104
|
-
@user = options[:user]
|
105
|
-
@root = options[:root]
|
106
|
-
|
107
|
-
CMDB::FileSource.base_directories = @keys unless @keys.empty?
|
108
|
-
CMDB::ConsulSource.url = @consul_url unless @consul_url.nil?
|
109
|
-
if !@consul_prefixes.nil? && !@consul_prefixes.empty?
|
110
|
-
CMDB::ConsulSource.prefixes = @consul_prefixes
|
111
|
-
end
|
112
|
-
|
113
|
-
CMDB.log.level = Logger::FATAL if options[:quiet]
|
69
|
+
@dir = rewrite
|
70
|
+
@pretend = pretend
|
71
|
+
@user = user
|
114
72
|
end
|
115
73
|
|
116
74
|
# Run the shim.
|
117
75
|
#
|
118
76
|
# @raise [SystemExit] if something goes wrong
|
119
77
|
def run
|
120
|
-
@cmdb = CMDB::Interface.new(root: @root)
|
121
|
-
|
122
78
|
rewrote = rewrite_files
|
123
79
|
populated = populate_environment
|
124
80
|
|
@@ -187,8 +143,6 @@ Where [options] are selected from:
|
|
187
143
|
|
188
144
|
# @return [Boolean]
|
189
145
|
def populate_environment
|
190
|
-
return false unless @env
|
191
|
-
|
192
146
|
env = @cmdb.to_h
|
193
147
|
|
194
148
|
env.keys.each do |k|
|
@@ -207,81 +161,12 @@ Where [options] are selected from:
|
|
207
161
|
|
208
162
|
def launch_app
|
209
163
|
if @command.any?
|
210
|
-
# log this now, so that it gets logged even if @pretend
|
211
164
|
CMDB.log.info "App will run as user #{@user}" if @user
|
212
|
-
|
213
|
-
|
214
|
-
CMDB.log.info "SIG#{@signal}-on-edit is enabled; fork app"
|
215
|
-
fork_and_watch_app unless @pretend
|
216
|
-
else
|
217
|
-
CMDB.log.info "SIG#{@signal}-on-edit is disabled; exec app"
|
218
|
-
exec_app unless @pretend
|
219
|
-
end
|
165
|
+
self.class.drop_privileges(@user) if @user
|
166
|
+
exec(*@command)
|
220
167
|
end
|
221
168
|
end
|
222
169
|
|
223
|
-
def exec_app
|
224
|
-
self.class.drop_privileges(@user) if @user
|
225
|
-
exec(*@command)
|
226
|
-
end
|
227
|
-
|
228
|
-
def fork_and_watch_app
|
229
|
-
# let the child share our stdio handles on purpose
|
230
|
-
pid = fork do
|
231
|
-
exec_app
|
232
|
-
end
|
233
|
-
|
234
|
-
CMDB.log.info('App (pid %d) has been forked; watching %s' % [pid, ::Dir.pwd])
|
235
|
-
|
236
|
-
t0 = Time.at(0)
|
237
|
-
|
238
|
-
listener = Listen.to(::Dir.pwd) do |modified, added, removed|
|
239
|
-
modified = modified.select { |fn| interesting?(fn) }
|
240
|
-
added = added.select { |fn| interesting?(fn) }
|
241
|
-
removed = removed.select { |fn| interesting?(fn) }
|
242
|
-
next if modified.empty? && added.empty? && removed.empty?
|
243
|
-
|
244
|
-
begin
|
245
|
-
dt = Time.now - t0
|
246
|
-
if dt > 15
|
247
|
-
Process.kill(@signal, pid)
|
248
|
-
CMDB.log.info 'Sent SIG%s to app (pid %d) because (modified,created,deleted)=(%d,%d,%d)' %
|
249
|
-
[@signal, pid, modified.size, added.size, removed.size]
|
250
|
-
t0 = Time.now
|
251
|
-
else
|
252
|
-
CMDB.log.error 'Skipped SIG%s to app (pid %d) due to timeout (%d)' %
|
253
|
-
[@signal, pid, dt]
|
254
|
-
end
|
255
|
-
rescue
|
256
|
-
CMDB.log.error 'Skipped SIG%s to app (pid %d) due to %s' %
|
257
|
-
[@signal, pid, $ERROR_INFO.to_s]
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
listener.start
|
262
|
-
|
263
|
-
wpid = nil
|
264
|
-
wstatus = nil
|
265
|
-
|
266
|
-
loop do
|
267
|
-
begin
|
268
|
-
wpid, wstatus = Process.wait2(-1, Process::WNOHANG)
|
269
|
-
if wpid
|
270
|
-
break if wstatus.exited?
|
271
|
-
CMDB.log.info('Descendant (pid %d) has waited with %s' % [wpid, wstatus.inspect])
|
272
|
-
end
|
273
|
-
rescue
|
274
|
-
CMDB.log.error 'Skipped wait2 to app (pid %d) due to %s' %
|
275
|
-
[pid, $ERROR_INFO.to_s]
|
276
|
-
end
|
277
|
-
sleep(1)
|
278
|
-
end
|
279
|
-
|
280
|
-
CMDB.log.info('App (pid %d) has exited with %s' % [wpid, wstatus.inspect])
|
281
|
-
listener.stop
|
282
|
-
exit(wstatus.exitstatus || 43)
|
283
|
-
end
|
284
|
-
|
285
170
|
def report_rewrite(total)
|
286
171
|
CMDB.log.info "Replaced #{total} variables in #{@dir}"
|
287
172
|
end
|