FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Device-mapper Development

 
 
LinkBack Thread Tools
 
Old 02-07-2012, 10:02 PM
Will Woods
 
Default anaconda_optparse.py: a new OptionParser that also reads boot args

This commit adds AnacondaOptionParser, which is an OptionParser subclass
that parses kernel boot arguments in addition to commandline arguments.

It looks for boot args that match the parser's long options. You can
also provide extra boot args to look for, e.g.:

op.add_option("--kickstart", "ks", dest="ksfile")

This patch also switches anaconda over to the new parser, which means we no
longer need loader to parse boot args for us.

NOTE BEHAVIOR CHANGE: anaconda now expects (but does not yet require)
all boot arguments to begin with "inst.", and will emit warning
log messages if you use the old forms (repo=..., ks=..., etc.).
---
anaconda | 19 ++++--
pyanaconda/anaconda_optparse.py | 116 +++++++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+), 6 deletions(-)
create mode 100644 pyanaconda/anaconda_optparse.py

diff --git a/anaconda b/anaconda
index 149be4a4..f236397 100755
--- a/anaconda
+++ b/anaconda
@@ -31,7 +31,6 @@
# This toplevel file is a little messy at the moment...

import atexit, sys, os, re, time, subprocess
-from optparse import OptionParser
from tempfile import mkstemp

# keep up with process ID of the window manager if we start it
@@ -190,7 +189,9 @@ def getAnacondaVersion():
return _isys.getAnacondaVersion()

def parseOptions(argv = None):
- op = OptionParser(version="%prog " + getAnacondaVersion())
+ from pyanaconda.anaconda_optparse import AnacondaOptionParser
+ op = AnacondaOptionParser(version="%prog " + getAnacondaVersion(),
+ bootarg_prefix="inst.", require_prefix=False)

# Interface
op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c",
@@ -208,9 +209,9 @@ def parseOptions(argv = None):
# Method of operation
op.add_option("--autostep", action="store_true", default=False)
op.add_option("-d", "--debug", dest="debug", action="store_true", default=False)
- op.add_option("--kickstart", dest="ksfile")
+ op.add_option("--kickstart", "ks", dest="ksfile")
op.add_option("--rescue", dest="rescue", action="store_true", default=False)
- op.add_option("--targetarch", dest="targetArch", nargs=1, type="string")
+ op.add_option("--targetarch", "rpmarch", dest="targetArch", type="string")

op.add_option("-m", "--method", dest="method", default=None)
op.add_option("--repo", dest="method", default=None)
@@ -256,11 +257,13 @@ def parseOptions(argv = None):
# Miscellaneous
op.add_option("--module", action="append", default=[])
op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False)
+ # XXX updates should go away because dracut's gonna handle it
op.add_option("--updates", dest="updateSrc", action="store", type="string")
op.add_option("--dlabel", action="store_true", default=False)
op.add_option("--image", action="append", dest="images", default=[])

- return op.parse_args(argv)
+ (opts, args) = op.parse_args(argv)
+ return (opts, args, op.deprecated_bootargs)

def setupPythonPath():
sys.path.append('/usr/share/system-config-date')
@@ -585,7 +588,7 @@ if __name__ == "__main__":
setupPythonUpdates()

# do this early so we can set flags before initializing logging
- (opts, args) = parseOptions()
+ (opts, args, depr) = parseOptions()
from pyanaconda.flags import flags
if opts.images:
flags.imageInstall = True
@@ -604,6 +607,10 @@ if __name__ == "__main__":

log.info("%s %s" % (sys.argv[0], getAnacondaVersion()))

+ for arg in depr:
+ stdoutLog.warn("Boot argument '%s' is deprecated. "
+ "In the future, use 'inst.%s'.", arg, arg)
+
# pull this in to get product name and versioning
from pyanaconda import product
from pyanaconda.constants import ROOT_PATH
diff --git a/pyanaconda/anaconda_optparse.py b/pyanaconda/anaconda_optparse.py
new file mode 100644
index 0000000..87b1fcc
--- /dev/null
+++ b/pyanaconda/anaconda_optparse.py
@@ -0,0 +1,116 @@
+#
+# anaconda_optparse.py: option parsing for anaconda (CLI and boot args)
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Will Woods <wwoods@redhat.com>
+
+from flags import BootArgs
+from optparse import OptionParser, OptionConflictError
+
+class AnacondaOptionParser(OptionParser):
+ '
+ Subclass of OptionParser that also examines boot arguments.
+
+ If the "bootarg_prefix" keyword argument is set, it's assumed that all
+ bootargs will start with that prefix.
+
+ "require_prefix" is a bool:
+ False: accept the argument with or without the prefix.
+ True: ignore the argument without the prefix. (default)
+ '
+ def __init__(self, *args, **kwargs):
+ self._boot_arg = dict()
+ self.bootarg_prefix = kwargs.pop("bootarg_prefix","")
+ self.require_prefix = kwargs.pop("require_prefix",True)
+ OptionParser.__init__(self, *args, **kwargs)
+
+ def add_option(self, *args, **kwargs):
+ '
+ Add a new option - like OptionParser.add_option.
+
+ The long options will be added to the list of boot args, unless
+ the keyword argument 'bootarg' is set to False.
+
+ Positional arguments that don't start with '-' are considered extra
+ boot args to look for.
+
+ NOTE: conflict_handler is currently ignored for boot args - they will
+ always raise OptionConflictError if they conflict.
+ '
+ flags = [a for a in args if a.startswith('-')]
+ bootargs = [a for a in args if not a.startswith('-')]
+ do_bootarg = kwargs.pop("bootarg", True)
+ option = OptionParser.add_option(self, *flags, **kwargs)
+ bootargs += [flag[2:] for flag in option._long_opts]
+ if do_bootarg:
+ for b in bootargs:
+ if b in self._boot_arg:
+ raise OptionConflictError(
+ "conflicting bootopt string: %s" % b, option)
+ else:
+ self._boot_arg[b] = option
+ return option
+
+ def _get_bootarg_option(self, arg):
+ 'Find the correct Option for a given bootarg (if one exists)'
+ option = self._boot_arg.get(arg)
+ prefixed_option = self._boot_arg.get(self.bootarg_prefix+arg)
+ if not self.bootarg_prefix: return option
+ if self.require_prefix: return prefixed_option
+ # even if the prefix isn't required, we still prefer it
+ if prefixed_option: return prefixed_option
+ # deprecated option found? make a note of it.
+ if option: self.deprecated_bootargs.append(arg)
+ return option
+
+ def parse_boot_cmdline(self, cmdline, values=None):
+ '
+ Parse the boot cmdline and set appropriate values according to
+ the options set by add_option.
+
+ cmdline can be given as a string (to be parsed by BootArgs), or a
+ dict (or any object with .iteritems()) of {bootarg:value} pairs.
+
+ If cmdline is None, the cmdline data will be whatever BootArgs reads
+ by default (/proc/cmdline, /run/initramfs/etc/cmdline, /etc/cmdline).
+
+ If an option requires a value but the boot arg doesn't provide one,
+ we'll quietly not set anything.
+ '
+ if cmdline is None or type(cmdline) is str:
+ bootargs = BootArgs(cmdline)
+ else:
+ bootargs = cmdline
+ self.deprecated_bootargs = []
+ for arg, val in bootargs.iteritems():
+ option = self._get_bootarg_option(arg)
+ if option is None: continue
+ if option.takes_value() and val is None:
+ continue # TODO: emit a warning or something there?
+ option.process(arg, val, values, self)
+ return values
+
+ def parse_args(self, args=None, values=None, cmdline=None):
+ '
+ Like OptionParser.parse_args(), but also parses the boot cmdline.
+ (see parse_boot_cmdline for details on that process.)
+ Commandline arguments will override boot arguments.
+ '
+ if values is None: values = self.get_default_values()
+ v = self.parse_boot_cmdline(cmdline, values)
+ return OptionParser.parse_args(self, args, v)
--
1.7.7.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 09:57 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org