Skip to content

Commit cb3ce74

Browse files
committed
(#7749) Parse command line args and config file before loading app/face
This commit is mostly focused on solving the following chicken-and-egg problem: the way the code worked before, the command_line class would try to load an app before doing any parsing of the cli args or the puppet config file. However, we want to support being able to load apps and faces from the libdir... and if your libdir is in a non-standard location, which you've specified via the command line or config file, then the command_line class would fail to find any apps that were in your libdir and exit before it ever even looked at the cli args or the config file. To get around this, and to prepare for supporting the ability to run faces without an application stub, we needed to move the parsing of the cli args and config file to an earlier point in the lifecycle. The major changes in this commit are: * Move the initial parsing of the cli args and the config file out of application.rb and into command_line.rb so that they happen before puppet tries to locate apps/faces. * Remove all of the "should_parse_config" and "should_not_parse_config" options and tests from the various apps. These are not relevant any longer because we always need to parse the config file to make sure we know where the libdir is before we try to load faces / apps. * Introduce a new option parser implementation, to supplement and perhaps eventually replace our use of the Ruby stdlib OptionParser. The stdlib OptionParser has some very undesirable behaviors that are not configurable; the new PuppetOptionParser is a wrapper around an open source parser called "trollop"; it maintains the same API that OptionParser exposes, but gives us complete control over what is happening behind the scenes. Conflicts: spec/unit/util/command_line_spec.rb
1 parent 2fe5b25 commit cb3ce74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+566
-298
lines changed

ext/upload_facts.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
require 'puppet/network/http_pool'
1212

1313
class Puppet::Application::UploadFacts < Puppet::Application
14-
should_parse_config
1514
run_mode :master
1615

1716
option('--debug', '-d')

lib/puppet/application.rb

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -174,19 +174,6 @@ def controlled_run(&block)
174174
result
175175
end
176176

177-
def should_parse_config
178-
@parse_config = true
179-
end
180-
181-
def should_not_parse_config
182-
@parse_config = false
183-
end
184-
185-
def should_parse_config?
186-
@parse_config = true if ! defined?(@parse_config)
187-
@parse_config
188-
end
189-
190177
# used to declare code that handle an option
191178
def option(*options, &block)
192179
long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
@@ -230,7 +217,7 @@ def [](name)
230217
end
231218

232219
#
233-
# TODO: look into changing this into two methods (getter/setter)
220+
# TODO cprice: look into changing this into two methods (getter/setter)
234221
# --cprice 2012-03-06
235222
#
236223

@@ -259,10 +246,6 @@ def run_mode( mode_name = nil)
259246
exit
260247
end
261248

262-
def should_parse_config?
263-
self.class.should_parse_config?
264-
end
265-
266249
# override to execute code before running anything else
267250
def preinit
268251
end
@@ -291,15 +274,15 @@ def set_run_mode(mode)
291274
$puppet_application_mode = @run_mode
292275
$puppet_application_name = name
293276

294-
# XXXXXXXXXXX TODO: this is crap. need to refactor this so that applications have a hook to initialize
277+
# XXXXXXXXXXX TODO cprice: this is crap. need to refactor this so that applications have a hook to initialize
295278
# the settings that are specific to them; need to decide whether to formally specify the list of such
296279
# settings, or just allow them to run willy-nilly.
297280
if (mode.name == :master)
298281
Puppet.settings.set_value(:facts_terminus, "yaml", :mutable_defaults)
299282
end
300283

301284

302-
## TODO: get rid of this whole block, push it to some kind of application-specific hook or something
285+
## TODO cprice: get rid of this whole block, push it to some kind of application-specific hook or something
303286

304287
if Puppet.respond_to? :settings
305288
# This is to reduce the amount of confusion in rspec
@@ -316,12 +299,11 @@ def set_run_mode(mode)
316299

317300
# This is the main application entry point
318301
def run
319-
exit_on_fail("initialize") { hook('preinit') { preinit } }
320-
exit_on_fail("parse options") { hook('parse_options') { parse_options } }
321-
exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
322-
exit_on_fail("prepare for execution") { hook('setup') { setup } }
302+
exit_on_fail("initialize") { plugin_hook('preinit') { preinit } }
303+
exit_on_fail("parse application options") { plugin_hook('parse_options') { parse_options } }
304+
exit_on_fail("prepare for execution") { plugin_hook('setup') { setup } }
323305
exit_on_fail("configure routes from #{Puppet[:route_file]}") { configure_indirector_routes }
324-
exit_on_fail("run") { hook('run_command') { run_command } }
306+
exit_on_fail("run") { plugin_hook('run_command') { run_command } }
325307
end
326308

327309
def main
@@ -362,6 +344,11 @@ def parse_options
362344
# Create an option parser
363345
option_parser = OptionParser.new(self.class.banner)
364346

347+
# TODO cprice: document this better. We need to include the globals so that the app
348+
# has an opportunity to override them.
349+
# Might be able to make this a little more efficient by sharing the Parser object
350+
# betwween the command line class and this one.
351+
#
365352
# Add all global options to it.
366353
Puppet.settings.optparse_addargs([]).each do |option|
367354
option_parser.on(*option) do |arg|
@@ -385,22 +372,11 @@ def parse_options
385372
option_parser.parse!(self.command_line.args)
386373
end
387374

388-
def handlearg(opt, arg)
389-
# rewrite --[no-]option to --no-option if that's what was given
390-
if opt =~ /\[no-\]/ and !arg
391-
opt = opt.gsub(/\[no-\]/,'no-')
392-
end
393-
# otherwise remove the [no-] prefix to not confuse everybody
394-
opt = opt.gsub(/\[no-\]/, '')
395-
unless respond_to?(:handle_unknown) and send(:handle_unknown, opt, arg)
396-
# Puppet.settings.handlearg doesn't handle direct true/false :-)
397-
if arg.is_a?(FalseClass)
398-
arg = "false"
399-
elsif arg.is_a?(TrueClass)
400-
arg = "true"
401-
end
402-
Puppet.settings.handlearg(opt, arg)
403-
end
375+
376+
377+
def handlearg(opt, val)
378+
opt, val = Puppet::Util::CommandLine.clean_opt(opt, val)
379+
send(:handle_unknown, opt, val) if respond_to?(:handle_unknown)
404380
end
405381

406382
# this is used for testing
@@ -416,20 +392,14 @@ def help
416392
"No help available for puppet #{name}"
417393
end
418394

419-
private
420395

421-
def exit_on_fail(message, code = 1)
422-
yield
423-
rescue ArgumentError, RuntimeError, NotImplementedError => detail
424-
Puppet.log_exception(detail, "Could not #{message}: #{detail}")
425-
exit(code)
426-
end
427396

428-
def hook(step,&block)
397+
def plugin_hook(step,&block)
429398
Puppet::Plugins.send("before_application_#{step}",:application_object => self)
430399
x = yield
431400
Puppet::Plugins.send("after_application_#{step}",:application_object => self, :return_value => x)
432401
x
433402
end
403+
private :plugin_hook
434404
end
435405
end

lib/puppet/application/agent.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
class Puppet::Application::Agent < Puppet::Application
44

5-
should_parse_config
65
run_mode :agent
76

87
attr_accessor :args, :agent, :daemon, :host

lib/puppet/application/apply.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
class Puppet::Application::Apply < Puppet::Application
44

5-
should_parse_config
6-
75
option("--debug","-d")
86
option("--execute EXECUTE","-e") do |arg|
97
options[:code] = arg

lib/puppet/application/cert.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
class Puppet::Application::Cert < Puppet::Application
44

5-
should_parse_config
65
run_mode :master
76

87
attr_accessor :all, :ca, :digest, :signed

lib/puppet/application/describe.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ def list_providers(type)
170170
class Puppet::Application::Describe < Puppet::Application
171171
banner "puppet describe [options] [type]"
172172

173-
should_not_parse_config
174-
175173
option("--short", "-s", "Only list parameters without detail") do |arg|
176174
options[:parameters] = false
177175
end

lib/puppet/application/device.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
class Puppet::Application::Device < Puppet::Application
66

7-
should_parse_config
87
run_mode :agent
98

109
attr_accessor :args, :agent, :host

lib/puppet/application/doc.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require 'puppet/application'
22

33
class Puppet::Application::Doc < Puppet::Application
4-
should_not_parse_config
54
run_mode :master
65

76
attr_accessor :unknown_args, :manifest

lib/puppet/application/face_base.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
require 'pp'
55

66
class Puppet::Application::FaceBase < Puppet::Application
7-
should_parse_config
87
run_mode :agent
98

109
option("--debug", "-d") do |arg|

lib/puppet/application/filebucket.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
class Puppet::Application::Filebucket < Puppet::Application
44

5-
should_not_parse_config
6-
75
option("--bucket BUCKET","-b")
86
option("--debug","-d")
97
option("--local","-l")

0 commit comments

Comments
 (0)