364 lines
13 KiB
Python
Executable File
364 lines
13 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# (c) Copyright 2012-2020 HP Development Company, L.P.
|
|
#
|
|
# 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, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Author: Amarnath Chitumalla
|
|
#
|
|
|
|
__version__ = '1.0'
|
|
__title__ = 'Self Diagnse Utility and Healing Utility'
|
|
__mod__ = 'hp-doctor'
|
|
__doc__ = """Tool checks for the deprecated, plug-in, dependencies, queues, permission issues and provides self diagnose steps"""
|
|
|
|
|
|
# global import
|
|
import getopt
|
|
import os
|
|
import sys
|
|
import getpass
|
|
|
|
#local import
|
|
from base.g import *
|
|
from base.strings import *
|
|
try:
|
|
from base import utils, tui, module,queues, os_utils, services, smart_install
|
|
except ImportError as e:
|
|
if 'cupsext' in e.args[0] :
|
|
check_extension_module_env('cupsext')
|
|
else:
|
|
log.exception("")
|
|
sys.exit(1)
|
|
|
|
from installer.core_install import *
|
|
from check import DependenciesCheck
|
|
|
|
USAGE = [(__doc__, "", "name", True),
|
|
("Usage: %s [OPTIONS]" % __mod__, "", "summary", True),
|
|
utils.USAGE_SPACE,
|
|
utils.USAGE_MODE,
|
|
("Run in interactive mode:", "-i or --interactive (Default)", "option", False),
|
|
# ("Run in graphical UI mode:", "-u or --gui (future use)", "option", False),
|
|
utils.USAGE_SPACE,
|
|
utils.USAGE_OPTIONS,
|
|
utils.USAGE_HELP,
|
|
utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
|
|
# ("Non-interactive mode:","-n(Without asking permissions)(future use)","option",False),
|
|
# ("Perform the task for the given device id:","-d<device id>(future use)","option",False),
|
|
# ("Take options from the file instead of command line:","-f<file> (future use)","option",False)
|
|
|
|
]
|
|
|
|
##########################global variables ##########################3
|
|
MODE = INTERACTIVE_MODE
|
|
DEVICE_URI = None
|
|
PERFORM_IN_NON_INTERACTIVE_MODE=False
|
|
LOG_LEVEL=None
|
|
VALID_AUTHENTICATION = False
|
|
IS_RESTART_REQ = False
|
|
DONOT_CLOSE_TERMINAL=False
|
|
SUMMARY_ONLY = False
|
|
|
|
#################################### functions #########################
|
|
def usage(typ='text'):
|
|
if typ == 'text':
|
|
utils.log_title(__title__, __version__)
|
|
|
|
utils.format_text(USAGE, typ, __title__, __mod__, __version__)
|
|
clean_exit(2)
|
|
|
|
|
|
def append_options(cmd):
|
|
if MODE == INTERACTIVE_MODE:
|
|
cmd += " -i "
|
|
elif MODE == GUI_MODE:
|
|
cmd += " -u "
|
|
|
|
if PERFORM_IN_NON_INTERACTIVE_MODE:
|
|
cmd += " -n "
|
|
|
|
if LOG_LEVEL:
|
|
cmd += " -l%s"%LOG_LEVEL
|
|
|
|
# Adding quiet mode option..
|
|
cmd += " -s "
|
|
return cmd
|
|
|
|
|
|
def authenticate(core):
|
|
global VALID_AUTHENTICATION
|
|
if not services.running_as_root() and VALID_AUTHENTICATION == False:
|
|
###TBD
|
|
# if MODE == GUI_MODE:
|
|
# GUI passwrd query..
|
|
# else:
|
|
if core.passwordObj.getAuthType() == "sudo":
|
|
tui.title("ENTER SUDO PASSWORD")
|
|
else:
|
|
tui.title("ENTER ROOT/SUPERUSER PASSWORD")
|
|
|
|
VALID_AUTHENTICATION = core.check_password()
|
|
else:
|
|
VALID_AUTHENTICATION = True
|
|
|
|
if not VALID_AUTHENTICATION:
|
|
log.error("3 incorrect attempts. (or) Insufficient permissions(i.e. try with sudo user).\nExiting.")
|
|
clean_exit(3)
|
|
|
|
return VALID_AUTHENTICATION
|
|
|
|
|
|
def install_plugin(core):
|
|
plugin_sts = core.get_plugin_status()
|
|
if plugin_sts == PLUGIN_VERSION_MISMATCH:
|
|
ok,user_input =tui.enter_choice("Found Plugin version mismatch. Press 'y' to re-install the plugin(y=yes*, n=no):",['y', 'n'], 'y')
|
|
elif plugin_sts == PLUGIN_FILES_CORRUPTED:
|
|
ok,user_input =tui.enter_choice("Plugins corrupted. Press 'y' to re-install the plugin(y=yes*, n=no):",['y', 'n'], 'y')
|
|
elif plugin_sts == PLUGIN_NOT_INSTALLED:
|
|
ok,user_input =tui.enter_choice("Plugin's are missing. Press 'y' to install the plugin(y=yes*, n=no):",['y', 'n'], 'y')
|
|
elif plugin_sts == PLUGIN_INSTALLED:
|
|
log.info("Plugin's already installed")
|
|
return True
|
|
else:
|
|
log.info("No plug-in printers are configured.")
|
|
return True
|
|
|
|
if ok and user_input == 'y':
|
|
# authenticate(core)
|
|
cmd='hp-plugin'
|
|
cmd = append_options(cmd)
|
|
sts = os_utils.execute(cmd)
|
|
if sts == 0:
|
|
return True
|
|
else:
|
|
log.info(log.bold("Failed to install Plugin. Please run 'hp-plugin' command to install plugin manually"))
|
|
return False
|
|
|
|
|
|
def deprecated_check(core):
|
|
if core.validate_distro_version():
|
|
log.debug("This distro is supported.")
|
|
log.info("No Deprecated items are found")
|
|
else:
|
|
log.error("This distro (i.e %s %s) is either deprecated or not yet supported."%(core.distro_name, core.distro_version))
|
|
ok,user_input =tui.enter_choice(log.red("The diagnosis is limited on unsupported platforms. Do you want to continue?(y=yes*, n=no):"),['y', 'n'], 'y')
|
|
if not ok or user_input !='y':
|
|
clean_exit(2)
|
|
|
|
|
|
def display_missing_dependencies(required_dependencies=[],optional_dependencies=[], missing_cmd=[]):
|
|
if len(required_dependencies):
|
|
log.info(log.bold("Missing Required Dependencies"))
|
|
log.info(log.bold('-'*len("Missing Required Dependencies")))
|
|
for packages_to_install in required_dependencies:
|
|
if 'cups' in packages_to_install:
|
|
log.error("'%s' package is missing or '%s' service is not running."%(packages_to_install,'cups'))
|
|
else:
|
|
log.error("'%s' package is missing/incompatible "%packages_to_install)
|
|
|
|
if len(optional_dependencies):
|
|
log.info(log.bold("Missing Optional Dependencies"))
|
|
log.info(log.bold('-'*len("Missing Optional Dependencies")))
|
|
for packages_to_install in optional_dependencies:
|
|
log.error("'%s' package is missing/incompatible "%packages_to_install)
|
|
|
|
if len(missing_cmd):
|
|
log.info(log.bold("Missing Commands"))
|
|
log.info(log.bold('-'*len("Missing Commands")))
|
|
for cmd in missing_cmd:
|
|
log.error("'%s' is missing"%cmd)
|
|
|
|
|
|
def clean_exit(exit_code=0):
|
|
mod.unlockInstance()
|
|
|
|
if DONOT_CLOSE_TERMINAL:
|
|
log.info("\n\nPlease close this terminal manually. ")
|
|
try:
|
|
while 1:
|
|
pass
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
sys.exit(exit_code)
|
|
|
|
|
|
#################################### Main #########################
|
|
log.set_module(__mod__)
|
|
try:
|
|
mod = module.Module(__mod__, __title__, __version__, __doc__, USAGE,
|
|
(INTERACTIVE_MODE, GUI_MODE),
|
|
(UI_TOOLKIT_QT3, UI_TOOLKIT_QT4, UI_TOOLKIT_QT5), True)
|
|
|
|
opts, device_uri, printer_name, mode, ui_toolkit, loc = \
|
|
mod.parseStdOpts('hl:gnid:f:w', ['summary-only','help', 'help-rest', 'help-man', 'help-desc', 'interactive', 'gui', 'lang=','logging=', 'debug'],
|
|
handle_device_printer=False)
|
|
|
|
except getopt.GetoptError as e:
|
|
log.error(e.msg)
|
|
usage()
|
|
|
|
if os.getenv("HPLIP_DEBUG"):
|
|
log.set_level('debug')
|
|
LOG_LEVEL = 'debug'
|
|
|
|
for o, a in opts:
|
|
if o == '-n':
|
|
MODE = NON_INTERACTIVE_MODE
|
|
PERFORM_IN_NON_INTERACTIVE_MODE = True
|
|
log.warn("NON_INTERACTIVE mode is not yet supported.")
|
|
#TBD
|
|
usage()
|
|
elif o == '-d':
|
|
DEVICE_URI=a
|
|
elif o in ('-u', '--gui'):
|
|
log.warn("GUI is not yet supported.")
|
|
#TBD
|
|
usage()
|
|
elif o == '-f':
|
|
log.warn("Option from file is not yet supported")
|
|
#TBD
|
|
usage()
|
|
elif o in ('-l', '--logging'):
|
|
LOG_LEVEL = a.lower().strip()
|
|
if not log.set_level(LOG_LEVEL):
|
|
usage()
|
|
elif o == '-w':
|
|
DONOT_CLOSE_TERMINAL = True
|
|
|
|
elif o == '--summary-only':
|
|
SUMMARY_ONLY = True
|
|
|
|
|
|
try:
|
|
if os.geteuid() == 0:
|
|
log.error("%s %s" %(__mod__, queryString(ERROR_RUNNING_AS_ROOT)))
|
|
sys.exit(1)
|
|
|
|
mod.lockInstance('')
|
|
mod.quiet= False
|
|
mod.showTitle()
|
|
log_file = os.path.normpath('%s/hp-doctor.log'%prop.user_dir)
|
|
|
|
if os.path.exists(log_file):
|
|
try:
|
|
os.remove(log_file)
|
|
except OSError:
|
|
pass
|
|
|
|
log.set_logfile(log_file)
|
|
log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
|
|
|
|
log.debug("Upgrade log saved in: %s" % log.bold(log_file))
|
|
log.debug("")
|
|
|
|
if PERFORM_IN_NON_INTERACTIVE_MODE and os.geteuid() != 0:
|
|
log.error("Non Interactive mode should be run in root mode.")
|
|
clean_exit(1)
|
|
|
|
ui_toolkit = sys_conf.get('configure','ui-toolkit')
|
|
|
|
dep = DependenciesCheck(MODE_CHECK,INTERACTIVE_MODE,ui_toolkit)
|
|
dep.core.init()
|
|
log.info(log.bold("\n\nChecking for Deprecated items...."))
|
|
|
|
deprecated_check(dep.core)
|
|
|
|
log.info(log.bold("\n\nChecking for HPLIP updates...."))
|
|
upgrade_cmd = utils.which('hp-upgrade',True)
|
|
if upgrade_cmd:
|
|
#checking for latest version of HPLIP.
|
|
upgrade_cmd = append_options(upgrade_cmd)
|
|
sts = os_utils.execute(upgrade_cmd)
|
|
if sts != 0:
|
|
log.error("Failed to upgrade latest HPLIP. Is hp-upgrade already running (i.e. foreground or background)?")
|
|
else:
|
|
log.error("Failed to locate hp-upgrade utility")
|
|
|
|
### Dependency check
|
|
log.info(log.bold("\n\nChecking for Dependencies...."))
|
|
if SUMMARY_ONLY:
|
|
num_errors, num_warns = dep.validate(DEPENDENCY_RUN_AND_COMPILE_TIME, True)
|
|
else:
|
|
num_errors, num_warns = dep.validate(DEPENDENCY_RUN_AND_COMPILE_TIME, False)
|
|
|
|
if num_errors or num_warns:
|
|
|
|
if dep.get_required_deps() or dep.get_optional_deps() or dep.get_cmd_to_run():
|
|
display_missing_dependencies(dep.get_required_deps(),dep.get_optional_deps(), dep.get_cmd_to_run())
|
|
authenticate(dep.core)
|
|
dep.core.install_missing_dependencies(INTERACTIVE_MODE,dep.get_required_deps(),dep.get_optional_deps(), dep.get_cmd_to_run())
|
|
|
|
log.info(log.bold("\n\nChecking Permissions...."))
|
|
# if not core.get_missing_user_grps() and not core.get_disable_selinux_status():
|
|
# if not core.get_disable_selinux_status():
|
|
# log.info("Permissions are correct.")
|
|
|
|
# if core.get_missing_user_grps():
|
|
# log.info(log.bold("Missing User Groups"))
|
|
# log.info(log.bold('-'*len("Missing User Groups")))
|
|
# log.info("%s"%core.get_missing_user_grps())
|
|
# authenticate(core)
|
|
# if core.add_groups_to_user(core.get_missing_user_grps(), core.get_user_grp_cmd()):
|
|
# IS_RESTART_REQ = True
|
|
|
|
# if core.get_disable_selinux_status():
|
|
# log.info(log.bold("SELinux Status"))
|
|
# log.info(log.bold('-'*len("SELinux Status")))
|
|
# log.info("SELinux is enabled. Needs to be disabled")
|
|
# authenticate(core)
|
|
# if core.disable_SELinux():
|
|
# IS_RESTART_REQ = True
|
|
|
|
log.info(log.bold("\n\nChecking for Configured Queues...."))
|
|
queues.main_function(dep.core.passwordObj, MODE,ui_toolkit, False, DEVICE_URI)
|
|
|
|
log.info(log.bold("\n\nChecking for HP Properitery Plugin's...."))
|
|
### Check for Plugin Printers
|
|
install_plugin(dep)
|
|
|
|
smart_ins_dev_list = smart_install.get_smartinstall_enabled_devices()
|
|
if smart_ins_dev_list:
|
|
log.info(log.bold("\n\nChecking for 'CD-ROM'/'Smart Install' Detected Devices...."))
|
|
url, tool_name = smart_install.get_SmartInstall_tool_info()
|
|
for printer in smart_ins_dev_list:
|
|
log.error("Smart Install is Enabled in '%s' Printer. This needs to be disabled."%printer)
|
|
log.info(log.bold("\nRefer link '%s' to disable Smart Install manually.\n"%(url)))
|
|
|
|
comm_err_dev = dep.get_communication_error_devs()
|
|
if comm_err_dev:
|
|
log.info(log.bold("\n\nChecking for Printer Status...."))
|
|
for printer in comm_err_dev:
|
|
log.error("'%s' Printer is either Powered-OFF or Failed to communicate."%printer)
|
|
log.info(log.bold("Turn On Printer and re-run %s"%__mod__))
|
|
|
|
if IS_RESTART_REQ:
|
|
log.info(log.bold("\nPlease reboot the system before performing any function."))
|
|
|
|
log.info(log.bold("\nDiagnose completed...\n"))
|
|
log.info("")
|
|
log.info("")
|
|
log.info("More information on Troubleshooting,How-To's and Support is available on http://hplipopensource.com/hplip-web/index.html")
|
|
|
|
clean_exit(0)
|
|
|
|
|
|
except KeyboardInterrupt:
|
|
log.error("User exit")
|
|
clean_exit(1)
|
|
|