The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using https://tickets.puppetlabs.com. See the following page for information on filing tickets with JIRA:

Bug #19306

Puppet option parser accepts partial matches but doesn't use them to alter configuration values

Added by Charlie Sharpsteen about 3 years ago. Updated almost 3 years ago.

Status:AcceptedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:Faces
Target version:-
Affected Puppet version:3.0.0 Branch:
Keywords:options

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com


Description

This popped up during investigation of #19153.

When a Puppet command such as agent encounters an unknown option, it throws a warning:

# puppet agent --foo
Error: Could not parse application options: invalid option: --foo

Similarly, when it encounters a known option, it will alter a config value:

# puppet agent --configprint daemonize
true

# puppet agent --no-daemonize --configprint daemonize
false

However, the parser will also accept partial matches:

# puppet agent --no-daemoniz --configprint daemonize
true
# puppet agent --no-daemon --configprint daemonize
true
# puppet agent --no-da --configprint daemonize
true

Edge Cases:

# puppet agent --no-daemonizer --configprint daemonize
Error: Could not parse application options: invalid option: --no-daemonizer
# puppet agent --no-d --configprint daemonize
Error: Could not parse application options: ambiguous option: --no-d

The problems with partial matching is that the flags don’t alter configuration values and no warning or error is emitted to alert users that their input is incorrect or that their intentions are not being honored.


Related issues

Related to Puppet - Bug #19153: service puppet ensure stopped kills off cron-run puppet w... Accepted
Duplicated by Puppet - Bug #18938: puppet agent -t --env=foo flag no longer works in puppet 3.x Duplicate
Duplicated by Puppet - Bug #20818: The short version of --environment argument (--env) is no... Duplicate

History

#1 Updated by Charlie Sharpsteen almost 3 years ago

Drilled the problem down a bit. A command line invocation, such as puppet agent --no-daemon, goes through two rounds of option parsing. This first round occurs in /util/command_line.rb and ends up triggering a block of code in settings.rb:

def parse_global_options(args)
    # Create an option parser
    option_parser = PuppetOptionParser.new
    option_parser.ignore_invalid_options = true

    ...

The important things to note is that this first round uses PuppetOptionParser which is a modified Trollop parser and that ignore_invalid_options is set to true because at this point Puppet doesn’t know which subcommand is being executed. Because of this, the unknown --no-daemon flag slips through the first round of parsing without raising an error.

The second round of parsing occurs within the Application class in the parse_options method. This round of parsing uses the OptionParser class from the optparse module in the Ruby standard library. The OptionParser class is capable of autocorrecting --no-daemon to --no-daemonize and in fact always performs this correction—-there is no way to disable it. The command line arguments that match Puppet’s global settings are passed to the handlearg function… which ignores them completely.

There are a few issues here:

  • We process command line arguments with two different parsing classes. We should be using one class if possible to reduce differences in behavior.

  • The handlearg function never uses the information it is passed to adjust Puppet settings.

  • The OptionParser destroys the original flag that was passed by the user when performing partial matching, so there is no way for handlearg to raise a note or warning about the use of a partial match.

#2 Updated by Charlie Sharpsteen almost 3 years ago

  • Status changed from Unreviewed to Accepted
  • Affected Puppet version changed from 3.1.0 to 3.0.0

Also appears that partial matching works in the 2.7.x series but not 3.x. Bisected the change in behavior down to cb3ce74. Appears this is where the split between OptionParser and Trollop was introduced.

Also available in: Atom PDF