Hallo, dies ist ein Test.
PWD: /www/data-lst1/unixsoft/unixsoft/kaempfer/.public_html
Running in File Mode
Relative path: ./../.././../../../.././bin/aimanifest
Real path: /usr/bin/aimanifest
Zurück
#!/usr/bin/python3.7 -Es import solaris.no_site_packages # # Copyright (c) 2011, 2021, Oracle and/or its affiliates. # """ aimanifest.py: aimanifest commandline wrapper around Manifest Input Module """ import errno import gettext import logging import os import sys from optparse import OptionParser from traceback import print_exc import solaris_install.manifest_input as milib from solaris_install.logger import InstallLogger from solaris_install.manifest_input.mim import ManifestInput _ = gettext.translation('solaris_install_aimanifest', '/usr/share/locale', fallback=True).gettext AIM_LOGGER = None VALIDATE = True NO_VALIDATE = False class AimOptionParser(OptionParser): ''' OptionParser which provides error_w_errno() to return a more correct errno ''' def error_w_errno(self, errnum, message): ''' Log and display a message, and exit with errnum status ''' AIM_LOGGER.error(message) print(_("Usage:\n") + self.usage + "\n", file=sys.stderr) print(os.path.basename(sys.argv[0]) + ": error: " + message, file=sys.stderr) sys.exit(errnum) def usage(argv): ''' Assemble command usage string. ''' name = os.path.basename(argv[0]) usage_str = _( " %(name)s subcommand cmd_options\n" " subcommands:\n" " %(name)s add [-r] <path> <value> Add new element\n" " %(name)s set [-r] <path> <value> " "Change values or add/change attributes\n" " %(name)s delete <path> Remove elements\n" " %(name)s get [-r] <path> " "Retrieve element values or attributes\n" " %(name)s load [-i] <filename> " "Load / incrementally overlay XML file\n" " %(name)s validate Validate XML data\n" "\n The -r option to set/add/get displays the path of " "the returned element\n" " in terms of node IDs. This path may be used in " "subsequent calls to\n" " %(name)s to specify the affected element more directly.\n" "\n The following environment variables are read:\n" " AIM_MANIFEST: Pathname of the evolving manifest. " "(Must be set)\n" " AIM_DTD: Overrides the DTD given in the evolving manifest. " "(Optional)\n" " AIM_LOGFILE: Logfile for additional information. " "(Optional)\n") % {"name": name} return usage_str def _handle_error(error): ''' Display the error message, log the whole traceback and set errno Args: error: exception containing message and, if IOError, an errno. Assume messages are localized. Returns: errno: EINVAL unless overridden by an IOError exception's errno. ''' if isinstance(error, milib.MimMultMsgError): for msg in error.errors: # These messages come already localized. print(msg, file=sys.stderr) AIM_LOGGER.error(msg) else: print(str(error), file=sys.stderr) AIM_LOGGER.error(str(error)) rval = getattr(error, "errno", errno.EINVAL) # Handle the cases where the errno field exists in the exception # but is None or 0 if not rval: rval = errno.EIO if isinstance(error, IOError) else errno.EINVAL return rval def _log_final_status(mim, title, paths=None): ''' Log status. Usually called after running a subcommand. Checks to see if the manifest validates, when this information would be logged. Does nothing if logging is disabled. Args: mim: Reference to the Manifest Input Module, needed for validation. title: Title that preceeds the "paths" argument in output, already localized. paths: List of nodepaths, used for printing only. ''' if AIM_LOGGER.isEnabledFor(logging.INFO): try: mim.validate() validated = _("Pass") except (milib.MimError, IOError): validated = _("Fail") out = _("cmd:success, validation:") + validated AIM_LOGGER.info(out) if paths: for path in paths: out = " %s: %s" % (title, path) AIM_LOGGER.info(out) def _setup_logging(): ''' Set up logging. If AIM_LOGFILE is set in the environment, enable logging to the file specified by AIM_LOGFILE. Enable logging at the level specified by the environment variable AIM_LOGLEVEL if set, else set to the INFO level by default. (These two variables (and logging here in general) is to support the Derived Manifest Module (DMM). ''' # pylint: disable-msg=W0603 global AIM_LOGGER logging.setLoggerClass(InstallLogger) AIM_LOGGER = logging.getLogger("aimanifest") logfile_name = os.environ.get("AIM_LOGFILE") if logfile_name is not None: try: logging.basicConfig(format="%(asctime)s: %(name)s: " "%(levelname)s: %(message)s", datefmt="%H:%M:%S", filename=logfile_name, filemode="a") except IOError as ioerr: (errnum, strerror) = ioerr.args raise SystemExit(_("AIM_LOGFILE I/O Error(%(errnum)s) :" "%(strerror)s : %(fname)s" % ({"errnum": errnum, "strerror": strerror, "fname": logfile_name}))) logging_level = os.environ.get("AIM_LOGLEVEL") if logging_level and logging_level.isdigit(): AIM_LOGGER.setLevel(int(logging_level)) else: AIM_LOGGER.setLevel(logging.INFO) else: logging.disable(logging.CRITICAL) def _shutdown_logging(): ''' Shut down logging. ''' logging.shutdown() def _do_aimanifest(argv): ''' Main. See usage for argv details. ''' usage_str = usage(argv) if len(argv) <= 1: AIM_LOGGER.error(_("Error: Missing subcommand")) print(_("Usage:\n") + usage_str, file=sys.stderr) return errno.EINVAL parser = AimOptionParser(usage=usage_str) parser.add_option("-i", "--incremental", dest="is_incremental", default=False, action="store_true", help=_("Do not clear data before adding new data")) parser.add_option("-r", "--return-path", dest="show_path", default=False, action="store_true", help=_("Return unique path to affected node")) (options, args) = parser.parse_args(argv[1:]) len_args = len(args) command = args[0] path = args[1] if (len_args > 1) else None value = args[2] if (len_args > 2) else None cmds_i_option = ["load"] cmds_r_option = ["add", "set", "get"] two_arg_cmds = ["add", "set"] one_arg_cmds = ["delete", "get", "load"] no_arg_cmds = ["validate"] if options.is_incremental and command not in cmds_i_option: parser.error_w_errno(errno.EINVAL, _("-i|--incremental is not applicable " "for given subcommand")) if options.show_path and command not in cmds_r_option: parser.error_w_errno(errno.EINVAL, _("-r|--return_path is not applicable " "for given subcommand")) if ((command in two_arg_cmds and (len_args < 3)) or (command in one_arg_cmds and (len_args < 2))): parser.error_w_errno(errno.EINVAL, _("missing argument")) if ((command in two_arg_cmds and (len_args > 3)) or (command in one_arg_cmds and (len_args > 2)) or (command in no_arg_cmds and (len_args > 1))): parser.error_w_errno(errno.EINVAL, _("extra arguments given")) aim_manifest = os.environ.get("AIM_MANIFEST") if aim_manifest is None: parser.error_w_errno(errno.EINVAL, _("AIM_MANIFEST environment variable is not set")) # Pass AIM_MANIFEST as the output file. try: mim = ManifestInput(aim_manifest, os.environ.get("AIM_DTD")) except (milib.MimError, IOError) as err: return (_handle_error(err)) if command == "add": AIM_LOGGER.info(_("command:%(mcommand)s, path:%(mpath)s, " "value:%(mvalue)s") % {"mcommand": command, "mpath": path, "mvalue": value}) try: path = mim.add(path, value) mim.commit(NO_VALIDATE) except (milib.MimError, IOError) as err: return (_handle_error(err)) _log_final_status(mim, _("Node"), [path]) if options.show_path: # Localization not needed here. print(path) elif command == "set": AIM_LOGGER.info(_("command:%(mcommand)s, path:%(mpath)s, " "value:%(mvalue)s") % {"mcommand": command, "mpath": path, "mvalue": value}) try: paths, is_attr = mim.set(path, value) mim.commit(NO_VALIDATE) except (milib.MimError, IOError) as err: return (_handle_error(err)) _log_final_status(mim, _("Node"), paths) if options.show_path: # Localization not needed here. for path in paths: print(path) elif is_attr: print(_("%d attribute(s) set") % len(paths)) else: print(_("%d element(s) set") % len(paths)) elif command == "get": AIM_LOGGER.info(_("command:%(mcommand)s, path:%(mpath)s") % {"mcommand": command, "mpath": path}) try: get_tuples = mim.get(path) except (milib.MimError, IOError) as err: return (_handle_error(err)) for (value, path) in get_tuples: if value is None or not len(value): value = '""' AIM_LOGGER.info(_("successful: returns value:%(mvalue)s, " "path:%(mpath)s") % {"mvalue": value, "mpath": path}) # Localization not needed here. if not options.show_path: print("%s" % value) else: print("%s %s" % (value, path)) elif command == "delete": AIM_LOGGER.info(_("command:%(mcommand)s, path:%(mpath)s") % {"mcommand": command, "mpath": path}) try: paths, is_attr = mim.delete(path) mim.commit(NO_VALIDATE) except (milib.MimError, IOError) as err: return (_handle_error(err)) _log_final_status(mim, _("Node"), paths) if is_attr: print(_("%d attribute(s) deleted") % len(paths)) else: print(_("%d element(s)/subtree(s) deleted") % len(paths)) elif command == "load": # path arg holds the filename AIM_LOGGER.info(_("command:%(mcommand)s, " "incremental:%(mincr)s, file:%(mfile)s") % {"mcommand": command, "mincr": str(options.is_incremental), "mfile": path}) try: mim.load(path, options.is_incremental) mim.commit(NO_VALIDATE) except (milib.MimError, IOError) as err: return (_handle_error(err)) _log_final_status(mim, _("File"), [path]) elif (command == "validate"): AIM_LOGGER.info(_("Command:%s") % command) try: mim.validate() AIM_LOGGER.info(_("Validation successful")) except (milib.MimError, IOError) as err: return (_handle_error(err)) else: AIM_LOGGER.error(_("Invalid subcommand \"%s\"") % command) print(_("Usage:\n") + usage_str, file=sys.stderr) return errno.EINVAL return 0 # No errors def main(argv): ''' Main program. ''' _setup_logging() rval = 1 try: rval = _do_aimanifest(argv) except Exception as err: # Catch unexpected exceptions, logging and displaying a traceback. print(str(err), file=sys.stderr) AIM_LOGGER.exception(str(err)) print_exc() _shutdown_logging() return rval if __name__ == "__main__": sys.exit(main(sys.argv))