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
42 if e.errno == errno.EACCES:
43 raise PermissionsError(dir)
44 elif e.errno == errno.ENOENT:
45 raise NoSuchDirectoryError(dir)
48 def makeLogger(options, numeric_args):
50 if logging_setup: return logging.getLogger()
51 context = " ".join(numeric_args)
52 logger = logging.getLogger()
53 logger.setLevel(logging.INFO)
54 stderr = logging.StreamHandler(sys.stderr)
55 stderr.setFormatter(logging.Formatter(" " * int(options.indent) + '%(levelname)s: %(message)s'))
56 dateFormat = "%H:%M:%S"
58 logformatter = logging.Formatter("%(asctime)s %(levelname)s -- " + context + ": %(message)s", dateFormat)
60 logformatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", dateFormat)
61 if not options.quiet: logger.addHandler(stderr)
62 else: logger.addHandler(NullLogHandler()) # prevent default
64 file = logging.FileHandler(options.log_file)
65 file.setFormatter(logformatter)
66 logger.addHandler(file)
67 if options.log_file_chmod:
68 os.chmod(options.log_file, int(options.log_file_chmod, 8))
70 logger.setLevel(logging.DEBUG)
72 stderr.setLevel(logging.WARNING)
73 if options.verbose or hasattr(options, "dry_run"):
74 stderr.setLevel(logging.INFO)
76 file.setLevel(logging.INFO)
80 def makeBaseArgs(options, **grab):
81 """Takes parsed options, and breaks them back into a command
82 line string that we can pass into a subcommand"""
84 grab["log_file"]= "--log-file"
85 grab["debug"] = "--debug"
86 grab["verbose"] = "--verbose"
87 grab["indent"] = "--indent"
88 grab["quiet"] = "--quiet"
89 #grab["log_db"] = "--log-db"
90 for k,flag in grab.items():
91 value = getattr(options, k)
92 if not value and k != "indent": continue
94 if type(value) is not bool:
97 args.append(str(value))
98 args.append("--context") # always have context for a subcommand
101 class NullLogHandler(logging.Handler):
102 """Log handler that doesn't do anything"""
103 def emit(self, record):
106 class WizardOptionParser(optparse.OptionParser):
107 """Configures some default user-level options"""
108 def __init__(self, *args, **kwargs):
109 kwargs["add_help_option"] = False
110 optparse.OptionParser.__init__(self, *args, **kwargs)
111 def parse_all(self, argv):
112 self.add_option("-h", "--help", action="help", help=optparse.SUPPRESS_HELP)
113 group = optparse.OptionGroup(self, "Common Options")
114 group.add_option("-v", "--verbose", dest="verbose", action="store_true",
115 default=False, help="Turns on verbose output")
116 group.add_option("--debug", dest="debug", action="store_true",
117 default=False, help="Turns on debugging output")
118 group.add_option("-q", "--quiet", dest="quiet", action="store_true",
119 default=False, help="Turns off output to stdout")
120 group.add_option("--log-file", dest="log_file",
121 default=None, help="Logs verbose output to file")
122 group.add_option("--log-file-chmod", dest="log_file_chmod",
123 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.")
124 group.add_option("--indent", dest="indent",
125 default=0, help="Indents stdout, useful for nested calls")
126 group.add_option("--context", dest="context", action="store_true",
127 default=False, help="Adds context to logs, useful for parallel processing")
128 self.add_option_group(group)
129 options, numeric_args = self.parse_args(argv)
130 makeLogger(options, numeric_args)
131 return options, numeric_args
133 class OptionBaton(object):
134 """Command classes may define options that they sub-commands may
135 use. Since wizard --global-command subcommand is not a supported
136 mode of operation, these options have to be passed down the command
137 chain until a option parser is ready to take it; this baton is
138 what is passed down."""
141 def add(self, *args, **kwargs):
142 key = kwargs["dest"] # require this to be set
143 self.store[key] = optparse.make_option(*args, **kwargs)
144 def push(self, option_parser, *args):
145 """Hands off parameters to option parser"""
147 option_parser.add_option(self.store[key])