11 class Error(wizard.Error):
12 """Base error class for all command errors"""
15 class PermissionsError(Error):
16 def __init__(self, dir):
21 ERROR: You don't have permissions to access this directory.
22 Do you have tokens for AFS with your root instance, and
23 is your root instance on scripts-security-upd?
25 You can check by running the commands 'klist' and
26 'blanche scripts-security-upd'.
29 class NoSuchDirectoryError(Error):
30 def __init__(self, dir):
35 ERROR: No such directory... check your typing
40 Parse the contents of an environment variable as a boolean.
41 This recognizes more values as ``False`` than :func:`bool` would.
52 except (ValueError, TypeError):
53 if val == "No" or val == "no" or val == "false" or val == "False":
61 if e.errno == errno.EACCES:
62 raise PermissionsError(dir)
63 elif e.errno == errno.ENOENT:
64 raise NoSuchDirectoryError(dir)
67 def makeLogger(options, numeric_args):
69 if logging_setup: return logging.getLogger()
70 context = " ".join(numeric_args)
71 logger = logging.getLogger()
72 logger.setLevel(logging.INFO)
73 stderr = logging.StreamHandler(sys.stderr)
74 stderr.setFormatter(logging.Formatter(" " * int(options.indent) + '%(levelname)s: %(message)s'))
75 dateFormat = "%H:%M:%S"
77 logformatter = logging.Formatter("%(asctime)s %(levelname)s -- " + context + ": %(message)s", dateFormat)
79 logformatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", dateFormat)
80 if not options.quiet: logger.addHandler(stderr)
81 else: logger.addHandler(NullLogHandler()) # prevent default
83 file = logging.FileHandler(options.log_file)
84 file.setFormatter(logformatter)
85 logger.addHandler(file)
86 if options.log_file_chmod:
87 os.chmod(options.log_file, int(options.log_file_chmod, 8))
89 logger.setLevel(logging.DEBUG)
91 stderr.setLevel(logging.WARNING)
92 if options.verbose or hasattr(options, "dry_run"):
93 stderr.setLevel(logging.INFO)
95 file.setLevel(logging.INFO)
99 def makeBaseArgs(options, **grab):
100 """Takes parsed options, and breaks them back into a command
101 line string that we can pass into a subcommand"""
103 grab["log_file"]= "--log-file"
104 grab["debug"] = "--debug"
105 grab["verbose"] = "--verbose"
106 grab["indent"] = "--indent"
107 grab["quiet"] = "--quiet"
108 #grab["log_db"] = "--log-db"
109 for k,flag in grab.items():
110 value = getattr(options, k)
111 if not value and k != "indent": continue
113 if type(value) is not bool:
116 args.append(str(value))
117 args.append("--context") # always have context for a subcommand
120 class NullLogHandler(logging.Handler):
121 """Log handler that doesn't do anything"""
122 def emit(self, record):
125 class WizardOptionParser(optparse.OptionParser):
126 """Configures some default user-level options"""
127 def __init__(self, *args, **kwargs):
128 kwargs["add_help_option"] = False
129 optparse.OptionParser.__init__(self, *args, **kwargs)
130 def parse_all(self, argv):
131 self.add_option("-h", "--help", action="help", help=optparse.SUPPRESS_HELP)
132 group = optparse.OptionGroup(self, "Common Options")
133 group.add_option("-v", "--verbose", dest="verbose", action="store_true",
134 default=boolish(os.getenv("WIZARD_VERBOSE")), help="Turns on verbose output. Environment variable is WIZARD_VERBOSE")
135 group.add_option("--debug", dest="debug", action="store_true",
136 default=boolish(os.getenv("WIZARD_DEBUG")), help="Turns on debugging output. Environment variable is WIZARD_DEBUG")
137 group.add_option("-q", "--quiet", dest="quiet", action="store_true",
138 default=boolish(os.getenv("WIZARD_QUIET")), help="Turns off output to stdout. Environment variable is WIZARD_QUIET")
139 group.add_option("--log-file", dest="log_file", metavar="FILE",
140 default=None, help="Logs verbose output to file")
141 group.add_option("--log-file-chmod", dest="log_file_chmod", metavar="CHMOD",
142 default=None, help="Chmod the log file after opening. Number is octal. You must chmod the log file 666 and place the file in /tmp if subprocesses are running as different users.")
143 group.add_option("--indent", dest="indent", metavar="WIDTH",
144 default=0, help="Indents stdout, useful for nested calls")
145 group.add_option("--context", dest="context", action="store_true",
146 default=False, help="Adds context to logs, useful for parallel processing")
147 self.add_option_group(group)
148 options, numeric_args = self.parse_args(argv)
149 makeLogger(options, numeric_args)
150 return options, numeric_args
152 class OptionBaton(object):
153 """Command classes may define options that they sub-commands may
154 use. Since wizard --global-command subcommand is not a supported
155 mode of operation, these options have to be passed down the command
156 chain until a option parser is ready to take it; this baton is
157 what is passed down."""
160 def add(self, *args, **kwargs):
161 key = kwargs["dest"] # require this to be set
162 self.store[key] = optparse.make_option(*args, **kwargs)
163 def push(self, option_parser, *args):
164 """Hands off parameters to option parser"""
166 option_parser.add_option(self.store[key])