1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# 4# (c) Copyright 2003-2015 HP Development Company, L.P. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19# 20# Author: Don Welch 21# 22 23# Std Lib 24import sys 25import os 26import os.path 27import re 28import time 29import grp 30import pwd 31import tarfile 32import stat 33import glob 34 35try: 36 import hashlib # new in 2.5 37 38 def get_checksum(s): 39 return hashlib.sha1(s).hexdigest() 40 41except ImportError: 42 import sha # deprecated in 2.6/3.0 43 44 def get_checksum(s): 45 return sha.new(s).hexdigest() 46 47 48# Local 49from base.g import * 50from base.codes import * 51from base import utils, tui, password, services, os_utils 52from .dcheck import * 53 54 55DISTRO_UNKNOWN = 0 56DISTRO_VER_UNKNOWN = '0.0' 57 58MODE_INSTALLER = 0 # hplip-install/hp-setup 59MODE_CHECK = 1 # hp-check 60MODE_CREATE_DOCS = 2 # create_docs 61 62TYPE_STRING = 1 63TYPE_LIST = 2 64TYPE_BOOL = 3 65TYPE_INT = 4 66 67DEPENDENCY_RUN_TIME = 1 68DEPENDENCY_COMPILE_TIME = 2 69DEPENDENCY_RUN_AND_COMPILE_TIME = 3 70 71DEPENDENCY_REQUIRED_INDEX = 0 72DEPENDENCY_DISPLAY_INDEX = 2 73 74# Mapping from patterns to probability contribution of pattern 75# Example code from David Mertz' Text Processing in Python. 76# Released in the Public Domain. 77err_pats = {r'(?is)<TITLE>.*?(404|403).*?ERROR.*?</TITLE>': 0.95, 78 r'(?is)<TITLE>.*?ERROR.*?(404|403).*?</TITLE>': 0.95, 79 r'(?is)<TITLE>ERROR</TITLE>': 0.30, 80 r'(?is)<TITLE>.*?ERROR.*?</TITLE>': 0.10, 81 r'(?is)<META .*?(404|403).*?ERROR.*?>': 0.80, 82 r'(?is)<META .*?ERROR.*?(404|403).*?>': 0.80, 83 r'(?is)<TITLE>.*?File Not Found.*?</TITLE>': 0.80, 84 r'(?is)<TITLE>.*?Not Found.*?</TITLE>': 0.40, 85 r'(?is)<BODY.*(404|403).*</BODY>': 0.10, 86 r'(?is)<H1>.*?(404|403).*?</H1>': 0.15, 87 r'(?is)<BODY.*not found.*</BODY>': 0.10, 88 r'(?is)<H1>.*?not found.*?</H1>': 0.15, 89 r'(?is)<BODY.*the requested URL.*</BODY>': 0.10, 90 r'(?is)<BODY.*the page you requested.*</BODY>': 0.10, 91 r'(?is)<BODY.*page.{1,50}unavailable.*</BODY>': 0.10, 92 r'(?is)<BODY.*request.{1,50}unavailable.*</BODY>': 0.10, 93 r'(?i)does not exist': 0.10, 94 } 95# Note:- If new utility is added, add same utility here to uninstall properly. 96 97BINS_LIST = ['hpijs', 'hp-align', 'hp-colorcal', 'hp-faxsetup', 'hp-linefeedcal', 'hp-pkservice', 'hp-printsettings', 'hp-sendfax', 'hp-timedate', 'hp-check', 'hp-devicesettings', 'hp-firmware', 'hp-makecopies', 'hp-plugin', 'hp-probe', 'hp-setup', 'hp-toolbox', 'hp-check-plugin', 'hp-diagnose_plugin', 98 'hp-info', 'hp-makeuri', 'hp-pqdiag', 'hp-query', 'hp-systray', 'hp-unload', 'hp-clean', 'hp-fab', 'hp-levels', 'hp-print', 'hp-scan', 'hp-testpage', 'hp-wificonfig', 'hp-upgrade', 'hplip-info', 'hp-check-upgrade', 'hp-config_usb_printer', 'hp-diagnose_queues', 'hp-devicesetup', 'hp-doctor', 'hp-logcapture'] 99 100LIBS_LIST = ['libhpmud.*', 'libhpip.*', 'sane/libsane-hpaio.*', 'cups/backend/hp', 'cups/backend/hpfax', 'cups/filter/hpcac','sane/libsane-hp2000S1*', 'libjpeg*', 101 'cups/filter/hpps', 'cups/filter/pstotiff', 'cups/filter/hpcups', 'cups/filter/hpcupsfax', 'cups/filter/hplipjs'] 102 103HPLIP_EXT_LIST = ['cupsext.so', 'cupsext.la', 'scanext.so', 'scanext.la', 104 'hpmudext.so', 'hpmudext.la', 'pcardext.so', 'pcardext.la'] 105 106FILES_LIST = ['/usr/local/share/cups/drv/hp/', '/usr/local/share/ppd/HP/', '/usr/local/share/cups/drv/hp/', '/usr/local/share/applications/hplip.desktop', '/usr/local/share/applications/hp-uiscan.desktop', 107 '/etc/xdg/autostart/hplip-systray.desktop', '/usr/local/etc/hp/hplip.conf', '/usr/local/share/doc/hplip-*', '/usr/lib/systemd/system/hplip-printer*.service'] 108 109RULES_LIST = ['56-hpmud.rules', '56-hpmud_sysfs.rules', '40-hplip.rules', '56-hpmud_support.rules', '56-hpmud_support_sysfs.rules', '55-hpmud.rules','S99-2000S1.rules', 110 '55-hpmud_sysfs.rules', '56-hpmud_add_printer.rules', '56-hpmud_add_printer_sysfs.rules', '86-hpmud-hp_*.rules', '86-hpmud_plugin.rules', '86-hpmud_plugin_sysfs.rules'] 111 112HPLIP_LIST = ['*.py', '*.pyc', 'base', 'copier', 'data', 'installer', 'pcard', 'ui4', 'ui', 'fax/*.py', 'fax/*.pyc', 113 'fax/pstotiff.convs', 'fax/pstotiff.types', 'fax/pstotiff', 'prnt/*.py', 'prnt/*.pyc', 'scan/*.py', 'scan/*.pyc'] 114 115PLUGIN_LIST = ['fax/plugins/', 'prnt/plugins/', 'scan/plugins/'] 116 117PLUGIN_STATE = ['/var/lib/hp/hplip.state'] 118 119 120# end 121 122 123OK_PROCESS_LIST = ['adept-notifier', 124 'adept_notifier', 125 'yum-updatesd', 126 ] 127 128CONFIGURE_ERRORS = {1: "General/unknown error", 129 2: "libusb not found", 130 3: "cups-devel not found", 131 4: "libnetsnmp not found", 132 5: "netsnmp-devel not found", 133 6: "python-devel not found", 134 7: "pthread-devel not found", 135 8: "ppdev-devel not found", 136 9: "libcups not found", 137 10: "libm not found", 138 11: "libusb-devel not found", 139 12: "sane-backends-devel not found", 140 13: "libdbus not found", 141 14: "dbus-devel not found", 142 15: "fax requires dbus support", 143 102: "libjpeg not found", 144 103: "jpeg-devel not found", 145 104: "libdi not found", 146 } 147 148 149EXTERNALDEP = 1 150GENERALDEP = 2 151COMPILEDEP = 3 152PYEXT = 4 153SCANCONF = 5 154 155JPEG_STR = "libjpeg - JPEG library" 156LIBTOOL_STR = "libtool - Library building support services" 157CUPS_STR = "CUPS - Common Unix Printing System" 158CUPS_DEV_STR = "CUPS devel- Common Unix Printing System development files" 159CUPS_IMG_STR = "CUPS image - CUPS image development files" 160GCC_STR = "gcc - GNU Project C and C++ Compiler" 161MAKE_STR = "make - GNU make utility to maintain groups of programs" 162THREAD_STR = "libpthread - POSIX threads library" 163GS_STR = "GhostScript - PostScript and PDF language interpreter and previewer" 164USB_STR = "libusb - USB library" 165CUPS_DDK_STR = "CUPS DDK - CUPS driver development kit" 166SANE_STR = "SANE - Scanning library" 167SANE_DEV_STR = "SANE - Scanning library development files" 168XSANE_STR = "xsane - Graphical scanner frontend for SANE" 169SCANIMAGE_STR = "scanimage - Shell scanning program" 170DBUS_STR = "DBus - Message bus system" 171POLKIT_STR = "PolicyKit - Administrative policy framework" 172SNMP_DEV_STR = "libnetsnmp-devel - SNMP networking library development files" 173CRYPTO_STR = "libcrypto - OpenSSL cryptographic library" 174NETWORK_STR = "network -wget" 175AVAHI_STR = "avahi-utils" 176PYTHON_STR = "Python 2.2 or greater - Python programming language" 177PYNTF_STR = "Python libnotify - Python bindings for the libnotify Desktop notifications" 178QT4DBUS_STR = "PyQt 4 DBus - DBus Support for PyQt4" 179QT4_STR = "PyQt 4- Qt interface for Python (for Qt version 4.x)" 180QT5DBUS_STR = "PyQt 5 DBus - DBus Support for PyQt5" 181QT5_STR = "PyQt 5- Qt interface for Python (for Qt version 4.x)" 182PYDBUS_STR = "Python DBus - Python bindings for DBus" 183PYXML_STR = "Python XML libraries" 184PY_DEV_STR = "Python devel - Python development files" 185PIL_STR = "PIL - Python Imaging Library (required for commandline scanning with hp-scan)" 186PIP_STR = "PIP - preferred installer program" 187TESS_STR = "Tesseract - Tesseract library for python" 188TESSEROCR_STR = "Tesserocr - Optical-character-recognition tesseract library for python" 189IMUTILS_STR = "Imutils - A series of basic image processing functions" 190OPENCV_STR = "Opencv - opencv library for python" 191ZBAR_STR = "ZBAR -zbar library for python" 192LEPTO_STR = "leptonica - leptonica library for python" 193#SETUPTOOLS_STR = "setuptools - library designed to facilitate packaging Python projects" 194PYPDF2_STR = "pypdf2 - pdf library for python" 195REPORTLAB_STR = "Reportlab - PDF library for Python" 196CUPSEXT_STR = 'CUPS-Extension' 197HPMUDEXT_STR = 'IO-Extension' 198HPAIO_STR = 'HPLIP-SANE-Backend' 199SCANEXT_STR = 'Scan-SANE-Extension' 200QT_STR = "Python-Qt" 201EPM_STR = "Build Debian Package" 202AUTOMAKE_STR = "Build Driver" 203 204APPARMOR_DIR = "/etc/apparmor.d" 205SELINUX_DIR = "/etc/selinux/targeted/policy/policy*" 206SEC_DICT = {"AppArmor": (APPARMOR_DIR, ["/etc/apparmor.d/usr.share.hplip", "/etc/apparmor.d/abstractions/hplip"]), 207 "SELinux": (SELINUX_DIR, ["/etc/selinux/targeted/modules/active/modules/hplip.pp"]) 208 } 209 210 211try: 212 from functools import update_wrapper 213except ImportError: # using Python version < 2.5 214 def trace(f): 215 def newf(*args, **kw): 216 log.debug("TRACE: func=%s(), args=%s, kwargs=%s" % 217 (f.__name__, args, kw)) 218 return f(*args, **kw) 219 newf.__name__ = f.__name__ 220 newf.__dict__.update(f.__dict__) 221 newf.__doc__ = f.__doc__ 222 newf.__module__ = f.__module__ 223 return newf 224else: # using Python 2.5+ 225 def trace(f): 226 def newf(*args, **kw): 227 log.debug("TRACE: func=%s(), args=%s, kwargs=%s" % 228 (f.__name__, args, kw)) 229 return f(*args, **kw) 230 return update_wrapper(newf, f) 231 232 233class CoreInstall(object): 234 235 def __init__(self, mode=MODE_INSTALLER, ui_mode=INTERACTIVE_MODE, 236 ui_toolkit='qt4'): 237 os.umask(0o022) 238 self.mode = mode 239 self.ui_mode = ui_mode 240 self.passwordObj = password.Password(ui_mode) 241 self.version_description, self.version_public, self.version_internal = '', '', '' 242 self.bitness = 32 243 self.endian = utils.LITTLE_ENDIAN 244 self.distro, self.distro_name, self.distro_version = DISTRO_UNKNOWN, '', DISTRO_VER_UNKNOWN 245 self.distro_version_supported = False 246 self.install_location = '/usr' 247 self.hplip_present = False 248 self.have_dependencies = {} 249 self.native_cups = True 250 self.ppd_dir = None 251 self.drv_dir = None 252 self.distros = {} 253 self.ui_toolkit = ui_toolkit 254 self.enable = None 255 self.disable = None 256 self.reload_dbus = False 257 self.security_package = "" 258 259 self.FIELD_TYPES = { 260 'distros': TYPE_LIST, 261 'index': TYPE_INT, 262 'versions': TYPE_LIST, 263 'display_name': TYPE_STRING, 264 'alt_names': TYPE_LIST, 265 'display': TYPE_BOOL, 266 'notes': TYPE_STRING, 267 'package_mgrs': TYPE_LIST, 268 'package_mgr_cmd': TYPE_STRING, 269 'pre_install_cmd': TYPE_LIST, 270 'pre_depend_cmd': TYPE_LIST, 271 'post_depend_cmd': TYPE_LIST, 272 'scanjet_depend_cmd': TYPE_LIST, 273 'scanjet_py3_depend_cmd': TYPE_LIST, 274 'hpoj_remove_cmd': TYPE_STRING, 275 'hplip_remove_cmd': TYPE_STRING, 276 'su_sudo': TYPE_STRING, 277 'ppd_install': TYPE_STRING, 278 'udev_mode_fix': TYPE_BOOL, 279 'ppd_dir': TYPE_STRING, 280 'drv_dir': TYPE_STRING, 281 'fix_ppd_symlink': TYPE_BOOL, 282 'code_name': TYPE_STRING, 283 'supported': TYPE_BOOL, # Supported by installer 284 'release_date': TYPE_STRING, 285 'packages': TYPE_LIST, 286 'commands': TYPE_LIST, 287 'same_as_version': TYPE_STRING, 288 'scan_supported': TYPE_BOOL, 289 'fax_supported': TYPE_BOOL, 290 'pcard_supported': TYPE_BOOL, 291 'network_supported': TYPE_BOOL, 292 'parallel_supported': TYPE_BOOL, 293 'usb_supported': TYPE_BOOL, 294 'packaged_version': TYPE_STRING, # Version of HPLIP pre-packaged in distro 295 'cups_path_with_bitness': TYPE_BOOL, 296 'ui_toolkit': TYPE_STRING, # qt3 or qt4 [or gtk] or none 297 'policykit': TYPE_BOOL, 298 'libusb01': TYPE_BOOL, 299 'udev_sysfs_rule': TYPE_BOOL, 300 'native_cups': TYPE_BOOL, 301 'package_available': TYPE_BOOL, 302 'package_arch': TYPE_LIST, 303 'open_mdns_port': TYPE_LIST, # command to use to open mdns multicast port 5353 304 'libdir_path': TYPE_STRING, 305 } 306 307 # components 308 # 'name': ('description', [<option list>]) 309 self.components = { 310 'hplip': ("HP Linux Imaging and Printing System", ['prnt', 'base', 'network', 'gui_qt4', 311 'gui_qt5', 'fax', 'scan', 'docs']), 312 } 313 314 self.selected_component = 'hplip' 315 316 # options 317 # name: (<required>, "<display_name>", [<dependency list>]), ... 318 self.options = { 319 # HPLIP 320 'prnt': (True, 'Print Component ', []), 321 'base': (True, 'Required HPLIP base components (including hpcups)', []), 322 'network': (False, 'Network/JetDirect I/O', []), 323 'gui_qt4': (False, 'Graphical User Interfaces (Qt4)', []), 324 'gui_qt5': (False, 'Graphical User Interfaces (Qt5)', []), 325 'gui_qt': (False, 'Graphical User Interfaces (Qt)', []), 326 'fax': (False, 'PC Send Fax support', []), 327 'scan': (False, 'Scanning support', []), 328 'docs': (False, 'HPLIP documentation (HTML)', []), 329 'policykit': (False, 'Administrative policy framework', []), 330 'libusb01': (False, 'libusb-1.0', []), 331 'udev_sysfs_rule': (False, 'udev_sysfs_rule', []), 332 } 333 334 # holds whether the user has selected (turned on each option) 335 # initial values are defaults (for GUI only) 336 self.selected_options = { 337 'prnt': False, 338 'base': True, 339 'network': True, 340 'gui_qt4': False, 341 'gui_qt5': False, 342 'gui_qt': False, 343 'fax': True, 344 'scan': True, 345 'docs': True, 346 'policykit': False, 347 'libusb01': False, 348 'udev_sysfs_rule': False, 349 'native_cups': False, 350 'class-driver': False, 351 } 352 353 # dependencies 354 # 'name': (<required or option>, [<option list>], <display_name>, <check_func>, <runtime/compiletime>), ... 355 # Note: any change to the list of dependencies must be reflected in 356 # base/distros.py 357 self.dependencies = { 358 # Required base packages 359 'epm': (False, ['prnt'], EPM_STR, self.check_epm, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', None, GENERALDEP), 360 'automake': (True, ['prnt'], AUTOMAKE_STR, self.check_automake, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', None, GENERALDEP), 361 'libjpeg': (True, ['base', 'prnt'], JPEG_STR, self.check_libjpeg, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', None, GENERALDEP), 362 'libtool': (True, ['base', 'prnt'], LIBTOOL_STR, self.check_libtool, DEPENDENCY_COMPILE_TIME, '-', 'libtool --version', COMPILEDEP), 363 'cups': (True, ['base', 'prnt'], CUPS_STR, self.check_cups, DEPENDENCY_RUN_TIME, '1.1', 'cups-config --version', EXTERNALDEP), 364 'cups-devel': (True, ['base', 'prnt'], CUPS_DEV_STR, self.check_cups_devel, DEPENDENCY_COMPILE_TIME, '-', 'cups-config --version', GENERALDEP), 365 'cups-image': (True, ['base', 'prnt'], CUPS_IMG_STR, self.check_cups_image, DEPENDENCY_COMPILE_TIME, '-', 'cups-config --version', GENERALDEP), 366 'gcc': (True, ['base', 'prnt'], GCC_STR, self.check_gcc, DEPENDENCY_COMPILE_TIME, '-', 'gcc --version', COMPILEDEP), 367 'make': (True, ['base', 'prnt'], MAKE_STR, self.check_make, DEPENDENCY_COMPILE_TIME, '3.0', 'make --version', COMPILEDEP), 368 'libpthread': (True, ['base', 'prnt'], THREAD_STR, self.check_libpthread, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_libpthread_version', GENERALDEP), 369 'gs': (True, ['base', 'prnt'], GS_STR, self.check_gs, DEPENDENCY_RUN_TIME, '7.05', 'gs --version', EXTERNALDEP), 370 'libusb': (True, ['base'], USB_STR, self.check_libusb, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_libusb_version', GENERALDEP), 371 372 # Optional base packages 373 # req. for .drv PPD installs 374 'cups-ddk': (False, ['base', 'prnt'], CUPS_DDK_STR, self.check_cupsddk, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 375 376 377 # Required scan packages 378 'sane': (True, ['scan'], SANE_STR, self.check_sane, DEPENDENCY_RUN_TIME, '-', 'sane-config --version', GENERALDEP), 379 'sane-devel': (True, ['scan'], SANE_DEV_STR, self.check_sane_devel, DEPENDENCY_COMPILE_TIME, '-', 'sane-config --version', GENERALDEP), 380 #'tesseract': (True, ['scan'], TESS_STR, self.check_tesseract, DEPENDENCY_RUN_TIME, '-', 'tesseract --version', GENERALDEP), 381 382 #'zbar': (True, ['scan'], ZBAR_STR, self.check_zbar, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 383 #'libleptonica': (True, ['scan'], LEPTO_STR, self.check_libleptonica, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 384 385 # Optional scan packages 386 'xsane': (False, ['scan'], XSANE_STR, self.check_xsane, DEPENDENCY_RUN_TIME, '0.9', 'FUNC#get_xsane_version', EXTERNALDEP), 387 'scanimage': (False, ['scan'], SCANIMAGE_STR, self.check_scanimage, DEPENDENCY_RUN_TIME, '1.0', 'scanimage --version', EXTERNALDEP), 388 389 # Required fax packages 390 'dbus': (True, ['fax'], DBUS_STR, self.check_dbus, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'dbus-daemon --version', EXTERNALDEP), 391 392 # Required and optional qt4 GUI packages 393 # optional for non-sudo behavior of plugins (only optional for Qt4 394 # option) 395 'policykit': (False, ['gui_qt4', 'gui_qt5'], POLKIT_STR, self.check_policykit, DEPENDENCY_RUN_TIME, '-', 'pkexec --version', EXTERNALDEP), 396 397 # Required network I/O packages 398 'libnetsnmp-devel': (True, ['network'], SNMP_DEV_STR, self.check_libnetsnmp, DEPENDENCY_RUN_AND_COMPILE_TIME, '5.0.9', 'net-snmp-config --version', GENERALDEP), 399 'libcrypto': (True, ['network'], CRYPTO_STR, self.check_libcrypto, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'openssl version', GENERALDEP), 400 'network': (False, ['network'], NETWORK_STR, self.check_wget, DEPENDENCY_RUN_TIME, '-', 'wget --version', EXTERNALDEP), 401 'avahi-utils': (False, ['network'], AVAHI_STR, self.check_avahi_utils, DEPENDENCY_RUN_TIME, '-', 'avahi-browse --version', EXTERNALDEP), 402 } 403 404 python2_dep = { 405 'python2X': (True, ['base'], PYTHON_STR, self.check_python, DEPENDENCY_RUN_AND_COMPILE_TIME, '2.2', 'python --version', GENERALDEP), 406 #'setuptools': (False, ['scan'], SETUPTOOLS_STR, self.check_setuptools, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 407 #'pip': (True, ['scan'], PIP_STR, self.check_pip, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 408 #'pypdf2': (True, ['scan'], PYPDF2_STR, self.check_pypdf2, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 409 #'opencv': (True, ['scan'], OPENCV_STR, self.check_opencv, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 410 #'zbar': (True, ['scan'], ZBAR_STR, self.check_zbar, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 411 # Optional for libnotify style popups from hp-systray 412 'python-notify': (False, ['gui_qt5', 'gui_qt4'], PYNTF_STR, self.check_pynotify, DEPENDENCY_RUN_TIME, '-', 'python-notify --version', GENERALDEP), 413 'pyqt4-dbus': (True, ['gui_qt4'], QT4DBUS_STR, self.check_pyqt4_dbus, DEPENDENCY_RUN_TIME, '4.0', 'FUNC#get_pyQt4_version', GENERALDEP), 414 # PyQt 4.x ) 415 'pyqt4': (True, ['gui_qt4'], QT4_STR, self.check_pyqt4, DEPENDENCY_RUN_TIME, '4.0', 'FUNC#get_pyQt4_version', GENERALDEP), 416 'pyqt5-dbus': (False, ['gui_qt5'], QT5DBUS_STR, self.check_pyqt5_dbus, DEPENDENCY_RUN_TIME, '5.0', 'FUNC#get_pyQt5_version', GENERALDEP), 417 # PyQt 5.x ) 418 'pyqt5': (True, ['gui_qt5'], QT5_STR, self.check_pyqt5, DEPENDENCY_RUN_TIME, '5.0', 'FUNC#get_pyQt5_version', GENERALDEP), 419 'python-dbus': (True, ['fax'], PYDBUS_STR, self.check_python_dbus, DEPENDENCY_RUN_TIME, '0.80.0', 'FUNC#get_python_dbus_ver', GENERALDEP), 420 'python-xml': (True, ['base'], PYXML_STR, self.check_python_xml, DEPENDENCY_RUN_TIME, '-', 'FUNC#get_python_xml_version', GENERALDEP), 421 'python-devel': (True, ['base'], PY_DEV_STR, self.check_python_devel, DEPENDENCY_COMPILE_TIME, '2.2', 'python --version', GENERALDEP), 422 'pil': (False, ['scan'], PIL_STR, self.check_pil, DEPENDENCY_RUN_TIME, '-', 'FUNC#get_pil_version', GENERALDEP), 423 #'imutils': (True, ['scan'], IMUTILS_STR, self.check_imutils, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 424 # Optional fax packages 425 'reportlab': (False, ['fax'], REPORTLAB_STR, self.check_reportlab, DEPENDENCY_RUN_TIME, '2.0', 'FUNC#get_reportlab_version', GENERALDEP), 426 #'tesserocr': (True, ['scan'], TESSEROCR_STR, self.check_tesserocr, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 427 428 } 429 430 python3_dep = { 431 'python3X': (True, ['base'], PYTHON_STR, self.check_python, DEPENDENCY_RUN_AND_COMPILE_TIME, '2.2', 'python3 --version', GENERALDEP), 432 # Optional for libnotify style popups from hp-systray 433 #'py3_setuptools': (False, ['scan'], SETUPTOOLS_STR, self.check_setuptools, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 434 #'python3-pip': (True, ['scan'], PIP_STR, self.check_pip3, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 435 #'pypdf2': (True, ['scan'], PYPDF2_STR, self.check_pypdf2, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 436 #'opencv': (True, ['scan'], OPENCV_STR, self.check_opencv, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 437 'python3-notify2': (False, ['gui_qt5', 'gui_qt4'], PYNTF_STR, self.check_pynotify, DEPENDENCY_RUN_TIME, '-', 'python-notify --version', GENERALDEP), 438 'python3-pyqt4-dbus': (False, ['gui_qt4'], QT4DBUS_STR, self.check_pyqt4_dbus, DEPENDENCY_RUN_TIME, '4.0', 'FUNC#get_pyQt4_version', GENERALDEP), 439 # PyQt 4.x ) 440 'python3-pyqt4': (True, ['gui_qt4'], QT4_STR, self.check_pyqt4, DEPENDENCY_RUN_TIME, '4.0', 'FUNC#get_pyQt4_version', GENERALDEP), 441 'python3-pyqt5-dbus': (False, ['gui_qt5'], QT5DBUS_STR, self.check_pyqt5_dbus, DEPENDENCY_RUN_TIME, '5.0', 'FUNC#get_pyQt5_version', GENERALDEP), 442 # PyQt 5.x ) 443 'python3-pyqt5': (True, ['gui_qt5'], QT5_STR, self.check_pyqt5, DEPENDENCY_RUN_TIME, '5.0', 'FUNC#get_pyQt5_version', GENERALDEP), 444 'python3-dbus': (True, ['fax'], PYDBUS_STR, self.check_python_dbus, DEPENDENCY_RUN_TIME, '0.80.0', 'FUNC#get_python_dbus_ver', GENERALDEP), 445 'python3-xml': (True, ['base'], PYXML_STR, self.check_python_xml, DEPENDENCY_RUN_TIME, '-', 'FUNC#get_python_xml_version', GENERALDEP), 446 'python3-devel': (True, ['base'], PY_DEV_STR, self.check_python_devel, DEPENDENCY_COMPILE_TIME, '2.2', 'python3 --version', GENERALDEP), 447 'python3-pil': (False, ['scan'], PIL_STR, self.check_pil, DEPENDENCY_RUN_TIME, '-', 'FUNC#get_pil_version', GENERALDEP), 448 #'imutils': (True, ['scan'], IMUTILS_STR, self.check_imutils, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 449 # Optional fax packages 450 'python3-reportlab': (False, ['fax'], REPORTLAB_STR, self.check_reportlab, DEPENDENCY_RUN_TIME, '2.0', 'FUNC#get_reportlab_version', GENERALDEP), 451 #'tesserocr': (True, ['scan'], TESSEROCR_STR, self.check_tesserocr, DEPENDENCY_RUN_TIME, '-', None, GENERALDEP), 452 } 453 454 from base.sixext import PY3 455 456 if PY3: 457 self.dependencies.update(python3_dep) 458 else: 459 self.dependencies.update(python2_dep) 460 461 self.hplip_dependencies = { 462 'cupsext': (True, ['base'], CUPSEXT_STR, self.check_cupsext, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_HPLIP_version', PYEXT), 463 'hpmudext': (True, ['base'], HPMUDEXT_STR, self.check_hpmudext, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_HPLIP_version', PYEXT), 464 'hpaio': (True, ['scan'], HPAIO_STR, self.check_hpaio, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_HPLIP_version', SCANCONF), 465 'scanext': (True, ['scan'], SCANEXT_STR, self.check_scanext, DEPENDENCY_RUN_AND_COMPILE_TIME, '-', 'FUNC#get_HPLIP_version', SCANCONF), 466 'pyqt': (True, ['gui_qt'], QT_STR, self.check_pyqt, DEPENDENCY_RUN_AND_COMPILE_TIME, '2.3', 'FUNC#get_pyQt_version', GENERALDEP), 467 } 468 469 self.version_func = { 470 'FUNC#get_python_dbus_ver': get_python_dbus_ver, 471 'FUNC#get_pyQt5_version': get_pyQt5_version, 472 'FUNC#get_pyQt4_version': get_pyQt4_version, 473 'FUNC#get_pyQt_version': get_pyQt_version, 474 'FUNC#get_reportlab_version': get_reportlab_version, 475 'FUNC#get_xsane_version': get_xsane_version, 476 'FUNC#get_pil_version': get_pil_version, 477 'FUNC#get_libpthread_version': get_libpthread_version, 478 'FUNC#get_python_xml_version': get_python_xml_version, 479 'FUNC#get_HPLIP_version': get_HPLIP_version, 480 'FUNC#get_libusb_version': get_libusb_version, 481 } 482 483 for opt in self.options: 484 update_spinner() 485 for d in self.dependencies: 486 if opt in self.dependencies[d][1]: 487 self.options[opt][2].append(d) 488 489 self.load_distros() 490 491 self.distros_index = {} 492 for d in self.distros: 493 self.distros_index[self.distros[d]['index']] = d 494 495 def init(self, callback=None): 496 if callback is not None: 497 callback("Init...\n") 498 499 update_spinner() 500 501 # Package manager names 502 self.package_mgrs = [] 503 for d in self.distros: 504 update_spinner() 505 506 for a in self.distros[d].get('package_mgrs', []): 507 if a and a not in self.package_mgrs: 508 self.package_mgrs.append(a) 509 510 self.version_description, self.version_public, self.version_internal = self.get_hplip_version() 511 log.debug("HPLIP Description=%s Public version=%s Internal version = %s" % 512 (self.version_description, self.version_public, self.version_internal)) 513 514 # have_dependencies 515 # is each dependency satisfied? 516 # start with each one 'No' 517 for d in self.dependencies: 518 update_spinner() 519 self.have_dependencies[d] = False 520 521 self.get_distro() 522 self.distro_name = self.distros_index[self.distro] 523 self.distro_changed() 524 525 if callback is not None: 526 callback("Distro: %s\n" % self.distro) 527 528 self.check_dependencies(callback) 529 530 for d in self.dependencies: 531 update_spinner() 532 533 log.debug("have %s = %s" % (d, self.have_dependencies[d])) 534 535 if callback is not None: 536 callback("Result: %s = %s\n" % (d, self.have_dependencies[d])) 537 538 pid, cmdline = utils.check_pkg_mgr(self.package_mgrs) 539 if pid: 540 log.debug("Running package manager: %s (%s)" % (cmdline, pid)) 541 542 self.bitness = utils.getBitness() 543 log.debug("Bitness = %d" % self.bitness) 544 545 update_spinner() 546 547 self.endian = utils.getEndian() 548 log.debug("Endian = %d" % self.endian) 549 550 update_spinner() 551 552 self.distro_version_supported = self.get_distro_ver_data( 553 'supported', False) 554 555 log.debug("Distro = %s Distro Name = %s Display Name= %s Version = %s Supported = %s" % 556 (self.distro, self.distro_name, self.distros[self.distro_name]['display_name'], 557 self.distro_version, self.distro_version_supported)) 558 559 update_spinner() 560 561 self.hplip_present = self.check_hplip() 562 log.debug("HPLIP (prev install) = %s" % self.hplip_present) 563 564 status, output = utils.run('cups-config --version', self.passwordObj) 565 self.cups_ver = output.strip() 566 log.debug("CUPS version = %s" % self.cups_ver) 567 568 if self.distro_name == "ubuntu": 569 self.reload_dbus = True 570 571 log.debug("DBUS configuration reload possible? %s" % self.reload_dbus) 572 573 status, self.sys_uname_info = utils.run('uname -a', self.passwordObj) 574 self.sys_uname_info = self.sys_uname_info.replace('\n', '') 575 log.debug(self.sys_uname_info) 576 577 # Record the installation time/date and version. 578 # Also has the effect of making the .hplip.conf file user r/w 579 # on the 1st run so that running hp-setup as root doesn't lock 580 # the user out of owning the file 581 user_conf.set('installation', 'date_time', 582 time.strftime("%x %H:%M:%S", time.localtime())) 583 user_conf.set('installation', 'version', self.version_public) 584 585 if callback is not None: 586 callback("Done") 587 588 def init_for_docs(self, distro_name, version, bitness=32): 589 self.distro_name = distro_name 590 self.distro_version = version 591 592 try: 593 self.distro = self.distros[distro_name]['index'] 594 except KeyError: 595 log.error("Invalid distro name: %s" % distro_name) 596 sys.exit(1) 597 598 self.bitness = bitness 599 600 for d in self.dependencies: 601 self.have_dependencies[d] = True 602 603 self.enable_ppds = self.get_distro_ver_data( 604 'ppd_install', 'ppd') == 'ppd' 605 self.ppd_dir = self.get_distro_ver_data('ppd_dir') 606 self.drv_dir = self.get_distro_ver_data('drv_dir') 607 608 self.distro_version_supported = True # for manual installs 609 610 def check_dependencies(self, callback=None): 611 update_ld_output() 612 613 for d in self.dependencies: 614 update_spinner() 615 616 log.debug("Checking for dependency '%s'...\n" % d) 617 618 if callback is not None: 619 callback("Checking: %s\n" % d) 620 621 self.have_dependencies[d] = self.dependencies[d][3]() 622 log.debug("have %s = %s" % (d, self.have_dependencies[d])) 623 624 cleanup_spinner() 625 626 def password_func(self): 627 if self.password: 628 return self.password 629 elif self.ui_mode == INTERACTIVE_MODE: 630 import getpass 631 return getpass.getpass("Enter password: ") 632 else: 633 return '' 634 635 def get_distro(self): 636 log.debug("Determining distro...") 637 name, ver = '', '0.0' 638 found = False 639 640 # Getting distro information using platform module 641 try: 642 import platform 643 try: 644 name = platform.dist()[0].lower() 645 ver = platform.dist()[1] 646 except AttributeError: 647 import distro 648 name = distro.linux_distribution()[0].lower() 649 ver = distro.linux_distribution()[1] 650 651 if not name: 652 found = False 653 log.debug("Not able to detect distro") 654 else: 655 found = True 656 log.debug("Able to detect distro") 657 except ImportError: 658 found = False 659 log.debug("Not able to detect distro in exception") 660 661 # Getting distro information using lsb_release command 662 # platform retrurn 'redhat' even for 'RHEL' or 'arch' for ManjaroLinux so re-reading using 663 # lsb_release. 664 if not found or name == 'redhat' or name == 'arch': 665 lsb_rel = utils.which("lsb_release", True) 666 if lsb_rel: 667 log.debug("Using 'lsb_release -is/-rs'") 668 status, name = utils.run(lsb_rel + ' -is', self.passwordObj) 669 if not status and name: 670 status, ver = utils.run(lsb_rel + ' -rs', self.passwordObj) 671 if not status and ver: 672 ver = ver.lower().strip() 673 found = True 674 675 # Getting distro information using /etc/issue file 676 if not found: 677 try: 678 name = open('/etc/issue', 'r').read().lower().strip() 679 except IOError: 680 found = False 681 else: 682 found = True 683 for n in name.split(): 684 m = n 685 if '.' in n: 686 m = '.'.join(n.split('.')[:2]) 687 688 try: 689 ver = float(m) 690 except ValueError: 691 try: 692 ver = int(m) 693 except ValueError: 694 ver = '0.0' 695 696 # Updating the distro name and version. 697 if found: 698 name = name.lower().strip() 699 log.debug("Distro name=%s" % name) 700 if name.find("redhatenterprise") > -1 or name.find("redhat") > -1: 701 name = "rhel" 702 703 log.debug("Distro version=%s" % ver) 704 if name == "rhel" and ver[0] == "5" and ver[1] == ".": 705 ver = "5.0" 706 elif name == "rhel" and ver[0] == "6" and ver[1] == ".": 707 ver = "6.0" 708 709 found_in_list = False 710 for d in self.distros: 711 if name.find(d) > -1: 712 self.distro = self.distros[d]['index'] 713 found_in_list = True 714 else: 715 for x in self.distros[d].get('alt_names', ''): 716 if x and name.find(x) > -1: 717 self.distro = self.distros[d]['index'] 718 found_in_list = True 719 break 720 if found_in_list: 721 break 722 723 self.distro_version = ver 724 self.distro_name = name 725 else: 726 log.warn("Failed to get the distro information.") 727 self.distro, self.distro_version = DISTRO_UNKNOWN, '0.0' 728 729 log.debug("distro=%d, distro_version=%s" % 730 (self.distro, self.distro_version)) 731 732 def distro_changed(self): 733 ppd_install = self.get_distro_ver_data('ppd_install', 'ppd') 734 735 if ppd_install not in ('ppd', 'drv'): 736 log.warning("Invalid ppd_install value: %s" % ppd_install) 737 738 self.enable_ppds = (ppd_install == 'ppd') 739 740 log.debug("Enable PPD install: %s (False=drv)" % self.enable_ppds) 741 742 self.ppd_dir = self.get_distro_ver_data('ppd_dir') 743 744 self.drv_dir = self.get_distro_ver_data('drv_dir') 745 if not self.enable_ppds and not self.drv_dir: 746 log.warning("Invalid drv_dir value: %s" % self.drv_dir) 747 748 self.distro_version_supported = self.get_distro_ver_data( 749 'supported', False) 750 self.selected_options['fax'] = self.get_distro_ver_data( 751 'fax_supported', True) 752 self.selected_options['network'] = self.get_distro_ver_data( 753 'network_supported', True) 754 self.selected_options['scan'] = self.get_distro_ver_data( 755 'scan_supported', True) 756 self.selected_options['policykit'] = self.get_distro_ver_data( 757 'policykit', False) 758 self.selected_options[ 759 'libusb01'] = self.get_distro_ver_data('libusb01', False) 760 self.selected_options['udev_sysfs_rule'] = self.get_distro_ver_data( 761 'udev_sysfs_rule', False) 762 self.native_cups = self.get_distro_ver_data('native_cups', False) 763 764 # Adjust required flag based on the distro ver ui_toolkit value 765 ui_toolkit = self.get_distro_ver_data('ui_toolkit', 'qt4').lower() 766 767 if ui_toolkit == 'qt4': 768 log.debug("Default UI toolkit: Qt4") 769 self.ui_toolkit = 'qt4' 770 self.selected_options['gui_qt4'] = True 771 elif ui_toolkit == 'qt5': 772 log.debug("Default UI toolkit: Qt5") 773 self.ui_toolkit = 'qt5' 774 self.selected_options['gui_qt5'] = True 775 776 # todo: gtk 777 # Override with --qt4 command args 778 if self.enable is not None: 779 if 'qt4' in self.enable: 780 log.debug("User selected UI toolkit: Qt4") 781 self.ui_toolkit = 'qt4' 782 self.selected_options['gui_qt4'] = True 783 elif 'qt5' in self.enable: 784 log.debug("User selected UI toolkit: Qt5") 785 self.ui_toolkit = 'qt5' 786 self.selected_options['gui_qt5'] = True 787 788 if self.disable is not None: 789 if 'qt4' in self.disable: 790 log.debug("User deselected UI toolkit: Qt4") 791 self.selected_options['gui_qt4'] = False 792 elif 'qt5' in self.disable: 793 log.debug("User deselected UI toolkit: Qt5") 794 self.selected_options['gui_qt5'] = False 795 796 def __fixup_data(self, key, data): 797 field_type = self.FIELD_TYPES.get(key, TYPE_STRING) 798 #log.debug("%s (%s) %d" % (key, data, field_type)) 799 800 if field_type == TYPE_BOOL: 801 return utils.to_bool(data) 802 803 elif field_type == TYPE_STRING: 804 if type('') == type(data): 805 return data.strip() 806 else: 807 return data 808 809 elif field_type == TYPE_INT: 810 try: 811 return int(data) 812 except ValueError: 813 return 0 814 815 elif field_type == TYPE_LIST: 816 return [x for x in data.split(',') if x] 817 818 def load_distros(self): 819 if self.mode == MODE_INSTALLER: 820 distros_dat_file = os.path.join('installer', 'distros.dat') 821 822 elif self.mode == MODE_CREATE_DOCS: 823 distros_dat_file = os.path.join( 824 '..', '..', 'installer', 'distros.dat') 825 826 else: # MODE_CHECK 827 distros_dat_file = os.path.join( 828 prop.home_dir, 'installer', 'distros.dat') 829 830 if not os.path.exists(distros_dat_file): 831 log.debug( 832 "DAT file not found at %s. Using local relative path..." % distros_dat_file) 833 distros_dat_file = os.path.join('installer', 'distros.dat') 834 835 distros_dat = ConfigBase(distros_dat_file) 836 distros_list = self.__fixup_data( 837 'distros', distros_dat.get('distros', 'distros')) 838 log.debug(distros_list) 839 840 for distro in distros_list: 841 update_spinner() 842 d = {} 843 844 if not distros_dat.has_section(distro): 845 log.debug( 846 "Missing distro section in distros.dat: [%s]" % distro) 847 continue 848 849 for key in distros_dat.keys(distro): 850 d[key] = self.__fixup_data(key, distros_dat.get(distro, key)) 851 852 self.distros[distro] = d 853 versions = self.__fixup_data( 854 "versions", distros_dat.get(distro, 'versions')) 855 self.distros[distro]['versions'] = {} 856 self.distros[distro]['versions_list'] = versions 857 858 for ver in versions: 859 same_as_version, supported = False, True 860 v = {} 861 ver_section = "%s:%s" % (distro, ver) 862 863 if not distros_dat.has_section(ver_section): 864 log.error( 865 "Missing version section in distros.dat: [%s:%s]" % (distro, ver)) 866 continue 867 868 if 'same_as_version' in distros_dat.keys(ver_section): 869 same_as_version = True 870 871 supported = self.__fixup_data( 872 'supported', distros_dat.get(ver_section, 'supported')) 873 874 for key in distros_dat.keys(ver_section): 875 v[key] = self.__fixup_data( 876 key, distros_dat.get(ver_section, key)) 877 878 self.distros[distro]['versions'][ver] = v 879 self.distros[distro]['versions'][ver]['dependency_cmds'] = {} 880 881 if same_as_version: # or not supported: 882 continue 883 884 for dep in self.dependencies: 885 dd = {} 886 dep_section = "%s:%s:%s" % (distro, ver, dep) 887 888 if not distros_dat.has_section(dep_section) and not same_as_version: 889 continue 890 891 # if same_as_version: 892 # continue 893 894 for key in distros_dat.keys(dep_section): 895 dd[key] = self.__fixup_data( 896 key, distros_dat.get(dep_section, key)) 897 898 self.distros[distro]['versions'][ 899 ver]['dependency_cmds'][dep] = dd 900 901 versions = self.distros[distro]['versions'] 902 for ver in versions: 903 ver_section = "%s:%s" % (distro, ver) 904 905 if 'same_as_version' in distros_dat.keys(ver_section): 906 v = self.__fixup_data("same_as_version", distros_dat.get( 907 ver_section, 'same_as_version')) 908 909 try: 910 import copy 911 vv = copy.deepcopy(self.distros[distro]['versions'][v]) 912 #vv = self.distros[distro]['versions'][v].copy() 913 vv['same_as_version'] = v 914 self.distros[distro]['versions'][ver] = vv 915 for key in distros_dat.keys(ver_section): 916 vv[key] = self.__fixup_data( 917 key, distros_dat.get(ver_section, key)) 918 dd = {} 919 for dep in self.dependencies: 920 dep_section = "%s:%s:%s" % (distro, ver, dep) 921 if not distros_dat.has_section(dep_section): 922 continue 923 924 for key in distros_dat.keys(dep_section): 925 dd[key] = self.__fixup_data( 926 key, distros_dat.get(dep_section, key)) 927 928 self.distros[distro]['versions'][ 929 ver]['dependency_cmds'][dep] = dd 930 931 except KeyError: 932 log.debug( 933 "Missing 'same_as_version=' version in distros.dat for section [%s:%s]." % (distro, v)) 934 continue 935 936 #import pprint 937 # pprint.pprint(self.distros) 938 939 def pre_install(self): 940 pass 941 942 def pre_depend(self): 943 pass 944 945 def check_python(self): 946 py_ver = sys.version_info 947 py_major_ver, py_minor_ver = py_ver[:2] 948 log.debug("Python ver=%d.%d" % (py_major_ver, py_minor_ver)) 949 return py_major_ver >= 2 950 951 def check_gcc(self): 952 return check_tool('gcc --version', 0) and check_tool('g++ --version', 0) 953 954 def check_make(self): 955 return check_tool('make --version', 3.0) 956 957 def check_libusb(self): 958 Is_libusb01_enabled = self.get_distro_ver_data('libusb01', False) 959 if Is_libusb01_enabled == True: 960 if not check_lib('libusb'): 961 return False 962 if self.distro_name != "rhel": 963 return len(locate_file_contains("usb.h", '/usr/local/include', 'usb_init')) 964 else: 965 return True 966 else: 967 if not check_lib('libusb-1.0'): 968 return False 969 if self.distro_name != "rhel": 970 return len(locate_file_contains("libusb.h", '/usr/local/include/libusb-1.0', 'libusb_init')) 971 else: 972 return True 973 974 def check_epm(self): 975 return check_tool('epm --version') 976 977 def check_automake(self): 978 return check_tool('automake --version') 979 980 def check_libjpeg(self): 981 return check_lib("libjpeg") and check_file("jpeglib.h") 982 983 def check_libcrypto(self): 984 return check_lib("libcrypto") and check_file("crypto.h") 985 986 def check_libpthread(self): 987 return check_lib("libpthread") and check_file("pthread.h") 988 989 def check_libnetsnmp(self): 990 return check_lib("libnetsnmp") and check_file("net-snmp-config.h") 991 992 def check_reportlab(self): 993 try: 994 log.debug("Trying to import 'reportlab'...") 995 import reportlab 996 997 ver = str(reportlab.Version) 998 log.debug("Version: %.1s" % ver) 999 if ver >= "2.0": 1000 log.debug("Success.") 1001 return True 1002 else: 1003 return False 1004 1005 except ImportError: 1006 log.debug("Failed.") 1007 return False 1008 1009 def check_python23(self): 1010 py_ver = sys.version_info 1011 py_major_ver, py_minor_ver = py_ver[:2] 1012 log.debug("Python ver=%d.%d" % (py_major_ver, py_minor_ver)) 1013 return py_major_ver >= 2 and py_minor_ver >= 3 1014 1015 def check_python_xml(self): 1016 try: 1017 import xml.parsers.expat 1018 except ImportError: 1019 return False 1020 else: 1021 return True 1022 1023 def check_sane(self): 1024 return check_lib('libsane') 1025 1026 def check_sane_devel(self): 1027 return len(locate_file_contains("sane.h", '/usr/local/include', 'extern SANE_Status sane_init')) 1028 1029 def check_xsane(self): 1030 if os.getenv('DISPLAY'): 1031 # will fail if X not running... 1032 return check_version(get_xsane_version(), '0.9') 1033# return check_tool('xsane --version', 0.9) # will fail if X not 1034# running... 1035 else: 1036 # ...so just see if it installed somewhere 1037 return bool(utils.which("xsane")) 1038 1039 def check_scanimage(self): 1040 return check_tool('scanimage --version', 1.0) 1041 1042 def check_gs(self): 1043 return check_tool('gs -v', 7.05) 1044 1045 def check_pyqt4(self): 1046 if self.ui_toolkit == 'qt4': 1047 try: 1048 import PyQt4 1049 except ImportError: 1050 return False 1051 else: 1052 return True 1053 else: 1054 return False 1055 1056 def check_pyqt5(self): 1057 if self.ui_toolkit == 'qt5': 1058 try: 1059 import PyQt5 1060 except ImportError: 1061 return False 1062 else: 1063 return True 1064 else: 1065 return False 1066 1067 def check_pyqt4_dbus(self): 1068 if self.ui_toolkit == 'qt4': 1069 try: 1070 from dbus.mainloop.qt import DBusQtMainLoop 1071 except ImportError: 1072 return False 1073 else: 1074 return True 1075 else: 1076 return False 1077 1078 def check_pyqt5_dbus(self): 1079 if self.ui_toolkit == 'qt5': 1080 try: 1081 from dbus.mainloop.pyqt5 import DBusQtMainLoop 1082 except ImportError: 1083 return False 1084 else: 1085 return True 1086 else: 1087 return False 1088 1089 def check_pyqt(self): 1090 if self.ui_toolkit == 'qt3': 1091 try: 1092 import qt 1093 except ImportError: 1094 return False 1095 else: 1096 return True 1097 1098 else: 1099 return False 1100 1101 def check_python_devel(self): 1102 dir_list = glob.glob('/usr/local/include/python%d*' % sys.version_info[0]) 1103 Found = False 1104 for p in dir_list: 1105 if check_file('Python.h', dir=p): 1106 Found = True 1107 break 1108 1109 return Found 1110 1111 def check_pynotify(self): 1112 try: 1113 import notify2 1114 except (ImportError, RuntimeError): 1115 try: 1116 import pynotify 1117 except (ImportError, RuntimeError): 1118 return False 1119 return True 1120 1121 def check_python_dbus(self): 1122 log.debug("Checking for python-dbus (>= 0.80)...") 1123 try: 1124 import dbus 1125 try: 1126 ver = dbus.version 1127 log.debug("Version: %s" % '.'.join( 1128 [str(x) for x in dbus.version])) 1129 return ver >= (0, 80, 0) 1130 1131 except AttributeError: 1132 try: 1133 ver = dbus.__version__ 1134 log.debug("Version: %s" % dbus.__version__) 1135 log.debug("HPLIP requires dbus version > 0.80.") 1136 return False 1137 1138 except AttributeError: 1139 log.debug( 1140 "Unknown version. HPLIP requires dbus version > 0.80.") 1141 return False 1142 1143 except ImportError: 1144 return False 1145 1146 def check_python_ctypes(self): 1147 try: 1148 import ctypes 1149 return True 1150 except ImportError: 1151 return False 1152 1153 def check_dbus(self): 1154 log.debug("Checking for dbus running and header files present (dbus-devel)...") 1155 if (self.distro_name.lower()=='fedora') and (self.distro_version>='30'): 1156 return True 1157 else: 1158 return check_ps(['dbus-daemon']) and \ 1159 len(locate_file_contains("dbus-message.h", 1160 '/usr/local/include', 'dbus_message_new_signal')) 1161 1162 def check_cups_devel(self): 1163 return check_file('cups.h') and bool(utils.which('lpr')) 1164 1165 def check_cups(self): 1166 status, output = utils.run('lpstat -r', self.passwordObj) 1167 if status > 0 or 'not running' in output: 1168 log.debug("CUPS is not running. %s" % output) 1169 return False 1170 else: 1171 log.debug("CUPS is running. %s " % output) 1172 return True 1173 1174 def check_cups_image(self): 1175 return check_file("raster.h", "/usr/local/include/cups") 1176 1177 def check_hplip(self): 1178 log.debug("Checking for HPLIP...") 1179 return locate_files('hplip.conf', '/usr/local/etc/hp') 1180 1181 def check_libtool(self): 1182 log.debug("Checking for libtool...") 1183 return check_tool('libtool --version') 1184 1185 '''def check_pip(self): 1186 return check_tool('pip2 --version') 1187 1188 def check_pip3(self): 1189 return check_tool('pip3 --version') 1190 1191 def check_tesseract(self): 1192 return check_tool('tesseract --version') 1193 1194 def check_opencv(self): 1195 try: 1196 import cv2 1197 return True 1198 except ImportError: 1199 return False 1200 1201 def check_tesserocr(self): 1202 try: 1203 import tesserocr 1204 return True 1205 except ImportError: 1206 return False 1207 1208 def check_imutils(self): 1209 try: 1210 import imutils 1211 return True 1212 except ImportError: 1213 return False 1214 1215 def check_zbar(self): 1216 return check_file("zbar.h", "/usr/local/include/") 1217 1218 def check_libleptonica(self): 1219 return check_file("allheaders.h", "/usr/local/include/leptonica") 1220 1221 def check_setuptools(self): 1222 try: 1223 import setuptools 1224 return True 1225 except ImportError: 1226 return False 1227 1228 def check_pypdf2(self): 1229 try: 1230 import PyPDF2 1231 return True 1232 except ImportError: 1233 return False 1234''' 1235 def check_pil(self): 1236 log.debug("Checking for PIL...") 1237 try: 1238 from PIL import Image 1239 return True 1240 except ImportError: 1241 return False 1242 1243 def check_cupsddk(self): 1244 log.debug("Checking for cups-ddk...") 1245 # TODO: Compute these paths some way or another... 1246 return check_file('media.defs', "/usr/local/share/cups/ppdc/") 1247 1248 def check_policykit(self): 1249 log.debug("Checking for PolicyKit...") 1250 if check_file('PolicyKit.conf', "/etc/PolicyKit") and check_file('org.gnome.PolicyKit.AuthorizationManager.service', "/usr/local/share/dbus-1/services"): 1251 return True 1252 elif check_file('50-localauthority.conf', "/etc/polkit-1/localauthority.conf.d") and check_file('org.freedesktop.PolicyKit1.service', "/usr/local/share/dbus-1/system-services"): 1253 return True 1254 elif check_file('org.freedesktop.PolicyKit1.conf', '/etc/dbus-1/system.d'): 1255 return True 1256 elif check_file('polkitd', "/usr/lib/polkit-1") and check_file('polkit-agent-helper-1', "/usr/lib/polkit-1") and check_file('polkit.conf', "/usr/lib/sysusers.d"): 1257 return True 1258 else: 1259 return False 1260 1261 def check_cupsext(self): 1262 log.debug("Checking 'cupsext' CUPS extension...") 1263 try: 1264 import cupsext 1265 except ImportError: 1266 log.error( 1267 "NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of cupsext.") 1268 return False 1269 else: 1270 return True 1271 1272 def check_hpmudext(self): 1273 log.debug("Checking 'hpmudext' I/O extension...") 1274 try: 1275 import hpmudext 1276 except ImportError: 1277 log.error( 1278 "NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of hpmudext.") 1279 return False 1280 else: 1281 return True 1282 1283 def check_pcardext(self): 1284 log.debug("Checking 'pcardext' Photocard extension...") 1285 try: 1286 import pcardext 1287 except ImportError: 1288 log.error( 1289 "NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of pcardext.") 1290 return False 1291 else: 1292 return True 1293 1294 def check_hpaio(self): 1295 found = False 1296 for path in ['/usr/local/etc/sane.d/dll.conf', '/usr/local/etc/sane.d/dll.d/hpaio', '/usr/local/etc/sane.d/dll.d/hplip']: 1297 log.debug("'Checking for hpaio' in '%s'..." % path) 1298 try: 1299 f = open(path, 'r') 1300 except IOError: 1301 log.info("'%s' not found." % path) 1302 else: 1303 for line in f: 1304 lineNoSpace = re.sub(r'\s', '', line) 1305 hpaiomatched = re.match('hpaio', lineNoSpace) 1306 if hpaiomatched: 1307 found = True 1308 break 1309 if found: 1310 break 1311 1312 if not found: 1313 log.error("'hpaio' not found in SANE conf files. Is SANE installed?") 1314 1315 return found 1316 1317 def update_hpaio(self): 1318 found = False 1319 home_dir = sys_conf.get('dirs', 'home') 1320 pat = re.compile(r"""(\S.*)share\/hplip""") 1321 usrbin_dir = None 1322 if pat.match(home_dir) is not None: 1323 usrlib_dir = pat.match(home_dir).group(1) + "lib/" 1324 if os.path.exists(usrlib_dir + 'sane/libsane-hpaio.so.1'): 1325 log.debug("'Updating hpaio' in '/usr/local/etc/sane.d/dll.conf'...") 1326 try: 1327 f = open('/usr/local/etc/sane.d/dll.conf', 'r') 1328 except IOError: 1329 log.error( 1330 "'/usr/local/etc/sane.d/dll.conf' not found. Creating dll.conf file") 1331 cmd = self.passwordObj.getAuthCmd() % 'touch /usr/local/etc/sane.d/dll.conf' 1332 log.debug("cmd=%s" % cmd) 1333 utils.run(cmd, self.passwordObj) 1334 else: 1335 for line in f: 1336 lineNoSpace = re.sub(r'\s', '', line) 1337 hpaiomatched = re.match('hpaio', lineNoSpace) 1338 if hpaiomatched: 1339 found = True 1340 break 1341 f.close() 1342 1343 if not found: 1344 st = os.stat('/usr/local/etc/sane.d/dll.conf') 1345 cmd = self.passwordObj.getAuthCmd() % 'chmod 777 /usr/local/etc/sane.d/dll.conf' 1346 log.debug("cmd=%s" % cmd) 1347 utils.run(cmd, self.passwordObj) 1348 try: 1349 f = open('/usr/local/etc/sane.d/dll.conf', 'a+') 1350 except IOError: 1351 log.error( 1352 "'/usr/local/etc/sane.d/dll.conf' not found. Creating dll.conf file") 1353 else: 1354 f.write('hpaio') 1355 f.close() 1356 actv_permissions = st.st_mode & 0o777 1357 cmd = 'chmod %o /usr/local/etc/sane.d/dll.conf' % actv_permissions 1358 cmd = self.passwordObj.getAuthCmd() % cmd 1359 log.debug("cmd=%s" % cmd) 1360 utils.run(cmd, self.passwordObj) 1361 return found 1362 1363 def check_scanext(self): 1364 log.debug("Checking 'scanext' SANE scanning extension...") 1365 found = False 1366 try: 1367 import scanext 1368 except ImportError: 1369 log.error( 1370 "NOT FOUND OR FAILED TO LOAD! Please reinstall HPLIP and check for the proper installation of scanext.") 1371 else: 1372 found = True 1373 return found 1374 1375 def security_package_status(self): 1376 found = ["", False] 1377 1378 for key in SEC_DICT.keys(): 1379 if glob.glob(SEC_DICT[key][0]): 1380 found[0] = key 1381 found[1] = all(map(glob.glob, SEC_DICT[key][1])) 1382 1383 return found 1384 1385 return found 1386 1387 def selinux_install(self): 1388 src_dir = os.getcwd() 1389 profile_location = src_dir + "/selinux/hplip.pp" 1390 profile_cmd = "semodule -n -i " + profile_location 1391 cmd = self.passwordObj.getAuthCmd() % profile_cmd 1392 log.info("Installing SELinux profile...") 1393 status, output = utils.run(cmd, self.passwordObj) 1394 1395 def get_hplip_version(self): 1396 self.version_description, self.version_public, self.version_internal = '', '', '' 1397 1398 if self.mode == MODE_INSTALLER: 1399 ac_init_pat = re.compile( 1400 r"""AC_INIT\(\[(.*?)\], *\[(.*?)\], *\[(.*?)\], *\[(.*?)\] *\)""", re.IGNORECASE) 1401 1402 try: 1403 config_in = open('./configure.in', 'r') 1404 except IOError: 1405 self.version_description, self.version_public, self.version_internal = \ 1406 '', sys_conf.get('configure', 'internal-tag', 1407 '0.0.0'), prop.installed_version 1408 else: 1409 for c in config_in: 1410 if c.startswith("AC_INIT"): 1411 match_obj = ac_init_pat.search(c) 1412 self.version_description = match_obj.group(1) 1413 self.version_public = match_obj.group(2) 1414 self.version_internal = match_obj.group(3) 1415 name = match_obj.group(4) 1416 break 1417 1418 config_in.close() 1419 1420 if name != 'hplip': 1421 log.error("Invalid archive!") 1422 1423 else: # MODE_CHECK 1424 try: 1425 self.version_description, self.version_public, self.version_internal = \ 1426 '', sys_conf.get('configure', 'internal-tag', 1427 '0.0.0'), prop.installed_version 1428 except KeyError: 1429 self.version_description, self.version_public, self.version_internal = '', '', '' 1430 1431 return self.version_description, self.version_public, self.version_internal 1432 1433 def configure(self, bClassDriver): 1434 configure_cmd = './configure' 1435 configuration = {} 1436 if PY3: 1437 dbus_avail = self.have_dependencies[ 1438 'dbus'] and self.have_dependencies['python3-dbus'] 1439 else: 1440 dbus_avail = self.have_dependencies[ 1441 'dbus'] and self.have_dependencies['python-dbus'] 1442 configuration['network-build'] = self.selected_options['network'] 1443 1444 if bClassDriver: 1445 configuration['scan-build'] = False 1446 configuration['fax-build'] = False 1447 configuration['dbus-build'] = False 1448 configuration['qt4'] = False 1449 configuration['qt5'] = False 1450 configuration['class-driver'] = True 1451 else: 1452 configuration['scan-build'] = self.selected_options['scan'] 1453 configuration[ 1454 'fax-build'] = self.selected_options['fax'] and dbus_avail 1455 configuration['dbus-build'] = dbus_avail 1456 configuration['qt4'] = self.selected_options['gui_qt4'] 1457 configuration['qt5'] = self.selected_options['gui_qt5'] 1458 configuration['class-driver'] = self.selected_options[ 1459 'class-driver'] 1460 1461 configuration['doc-build'] = self.selected_options['docs'] 1462 configuration['policykit'] = self.selected_options['policykit'] 1463 configuration['libusb01_build'] = self.selected_options['libusb01'] 1464 configuration['udev_sysfs_rules'] = self.selected_options[ 1465 'udev_sysfs_rule'] 1466 1467 # Setup printer driver configure flags based on distro data... 1468 if self.native_cups: # hpcups 1469 configuration['hpcups-install'] = True 1470 configuration['hpijs-install'] = False 1471 configuration['foomatic-ppd-install'] = False 1472 configuration['foomatic-drv-install'] = False 1473 1474 if self.enable_ppds: 1475 configuration['cups-ppd-install'] = True 1476 configuration['cups-drv-install'] = False 1477 else: 1478 configuration['cups-ppd-install'] = False 1479 configuration['cups-drv-install'] = True 1480 1481 else: # HPIJS/foomatic 1482 configuration['hpcups-install'] = False 1483 configuration['hpijs-install'] = True 1484 configuration['cups-ppd-install'] = False 1485 configuration['cups-drv-install'] = False 1486 1487 if self.enable_ppds: 1488 configuration['foomatic-ppd-install'] = True 1489 configuration['foomatic-drv-install'] = False 1490 else: 1491 configuration['foomatic-ppd-install'] = False 1492 configuration['foomatic-drv-install'] = True 1493 1494 # ... and then override and adjust for consistency with passed in parameters 1495 if self.enable is not None: 1496 for c in self.enable: 1497 if c == 'hpcups-install': 1498 configuration['hpijs-install'] = False 1499 configuration['foomatic-ppd-install'] = False 1500 configuration['foomatic-drv-install'] = False 1501 elif c == 'hpijs-install': 1502 configuration['hpcups-install'] = False 1503 configuration['cups-ppd-install'] = False 1504 configuration['cups-drv-install'] = False 1505 elif c == 'foomatic-ppd-install': 1506 configuration['foomatic-drv-install'] = False 1507 elif c == 'foomatic-drv-install': 1508 configuration['foomatic-ppd-install'] = False 1509 elif c == 'cups-ppd-install': 1510 configuration['cups-drv-install'] = False 1511 elif c == 'cups-drv-install': 1512 configuration['cups-ppd-install'] = False 1513 1514 if self.disable is not None: 1515 for c in self.disable: 1516 if c == 'hpcups-install': 1517 configuration['hpijs-install'] = True 1518 configuration['cups-ppd-install'] = False 1519 configuration['cups-drv-install'] = False 1520 elif c == 'hpijs-install': 1521 configuration['hpcups-install'] = True 1522 configuration['foomatic-ppd-install'] = False 1523 configuration['foomatic-drv-install'] = False 1524 elif c == 'foomatic-ppd-install': 1525 configuration['foomatic-drv-install'] = True 1526 elif c == 'foomatic-drv-install': 1527 configuration['foomatic-ppd-install'] = True 1528 elif c == 'cups-ppd-install': 1529 configuration['cups-drv-install'] = True 1530 elif c == 'cups-drv-install': 1531 configuration['cups-ppd-install'] = True 1532 1533 if self.ppd_dir is not None: 1534 configure_cmd += ' --with-hpppddir=%s' % self.ppd_dir 1535 1536 libdir_path = self.get_distro_ver_data('libdir_path', False) 1537 if libdir_path and self.bitness == 64: 1538 configure_cmd += ' --libdir=%s' % (libdir_path) 1539 elif self.bitness == 64: 1540 configure_cmd += ' --libdir=/usr/lib64' 1541 1542 configure_cmd += ' --prefix=%s' % self.install_location 1543 1544 if self.get_distro_ver_data('cups_path_with_bitness', False) and self.bitness == 64: 1545 configure_cmd += ' --with-cupsbackenddir=/usr/lib64/cups/backend --with-cupsfilterdir=/usr/lib64/cups/filter' 1546 1547 if self.enable is not None: 1548 for c in self.enable: 1549 configuration[c] = True 1550 1551 if self.disable is not None: 1552 for c in self.disable: 1553 configuration[c] = False 1554 1555 for c in configuration: 1556 if configuration[c]: 1557 configure_cmd += ' --enable-%s' % c 1558 else: 1559 configure_cmd += ' --disable-%s' % c 1560 1561 # For AppArmor Profiles 1562 if self.security_package == "AppArmor": 1563 configure_cmd += ' --enable-apparmor_build' 1564 if self.security_package == "SELinux": 1565 configure_cmd += ' --enable-selinux_build' 1566 1567 # For Unit/Functional testing changes. 1568 if ".internal" in prop.version and os.path.exists('testcommon/'): 1569 configure_cmd += ' --enable-hplip_testing_flag' 1570 1571 return configure_cmd 1572 1573 def configure_html(self): 1574 configure_cmd = './configure' 1575 configure_cmd += ' --prefix=/usr' 1576 configure_cmd += ' --with-hpppddir=%s' % self.ppd_dir 1577 1578 libdir_path = self.get_distro_ver_data('libdir_path', False) 1579 if libdir_path and self.bitness == 64: 1580 configure_cmd += ' --libdir=%s' % (libdir_path) 1581 elif self.bitness == 64: 1582 configure_cmd += ' --libdir=/usr/lib64' 1583 1584 self.ui_toolkit = self.get_distro_ver_data('ui_toolkit') 1585 if self.ui_toolkit is not None and self.ui_toolkit == 'qt3': 1586 configure_cmd += ' --enable-qt3 --disable-qt4' 1587 else: 1588 configure_cmd += ' --enable-qt4' 1589 1590 self.native_cups = self.get_distro_ver_data('native_cups') 1591 if self.native_cups is not None and self.native_cups == 1: 1592 if self.enable_ppds: 1593 configure_cmd += ' --enable-hpcups-install --disable-cups-drv-install --enable-cups-ppd-install --disable-hpijs-install --disable-foomatic-drv-install --disable-foomatic-ppd-install --disable-foomatic-rip-hplip-install' 1594 else: 1595 configure_cmd += ' --enable-hpcups-install --enable-cups-drv-install --disable-cups-ppd-install --disable-hpijs-install --disable-foomatic-drv-install --disable-foomatic-ppd-install --disable-foomatic-rip-hplip-install' 1596 else: 1597 configure_cmd += ' --disable-hpcups-install --disable-cups-drv-install --disable-cups-ppd-install --enable-hpijs-install --enable-foomatic-drv-install --enable-foomatic-ppd-install --enable-foomatic-rip-hplip-install' 1598 1599 self.fax_supported = self.get_distro_ver_data('fax_supported') 1600 if self.fax_supported is None: 1601 configure_cmd += ' --disable-fax-build --disable-dbus-build' 1602 else: 1603 configure_cmd += ' --enable-fax-build --enable-dbus-build' 1604 1605 self.network_supported = self.get_distro_ver_data('network_supported') 1606 if self.network_supported is None: 1607 configure_cmd += ' --disable-network-build' 1608 else: 1609 configure_cmd += ' --enable-network-build' 1610 1611 self.scan_supported = self.get_distro_ver_data('scan_supported') 1612 if self.scan_supported is None: 1613 configure_cmd += ' --disable-scan-build' 1614 else: 1615 configure_cmd += ' --enable-scan-build' 1616 1617 self.policykit = self.get_distro_ver_data('policykit') 1618 if self.policykit is not None and self.policykit == 1: 1619 configure_cmd += ' --enable-policykit' 1620 else: 1621 configure_cmd += ' --disable-policykit' 1622 1623 self.libusb01 = self.get_distro_ver_data('libusb01') 1624 if self.libusb01 is not None and self.libusb01 == 1: 1625 configure_cmd += ' --enable-libusb01_build' 1626 else: 1627 configure_cmd += ' --disable-libusb01_build' 1628 1629 self.udev_sysfs_rule = self.get_distro_ver_data('udev_sysfs_rule') 1630 if self.udev_sysfs_rule is not None and self.udev_sysfs_rule == 1: 1631 configure_cmd += ' --enable-udev_sysfs_rules' 1632 else: 1633 configure_cmd += ' --disable-udev_sysfs_rules' 1634 1635 configure_cmd += ' --enable-doc-build' 1636 1637 return configure_cmd 1638 1639 def build_cmds(self, bClassDriver, option): 1640 if option == 'i': 1641 cmnd = "make install" 1642 log.info("cmnd:%s" % cmnd) 1643 return [self.configure(bClassDriver), 1644 'make clean', 1645 'make', self.passwordObj.getAuthCmd() % cmnd] 1646 1647 elif option == 't': 1648 cmnd = "make dist" 1649 log.info("cmnd:%s" % cmnd) 1650 return [self.configure(bClassDriver), 1651 'make clean', 1652 'make', cmnd] 1653 1654 elif option == 'r': 1655 cmnd = "make rpm" 1656 log.info("cmnd:%s" % cmnd) 1657 return [self.configure(bClassDriver), 1658 'make clean', 1659 'make', cmnd] 1660 1661 elif option == 'b': 1662 cmnd = "make deb" 1663 log.info("cmnd:%s" % cmnd) 1664 return [self.configure(bClassDriver), 1665 'make clean', 1666 'make', self.passwordObj.getAuthCmd() % cmnd] 1667 1668 elif option == 'd': 1669 return [self.configure(bClassDriver), 1670 'make clean', 1671 'make', 1672 self.passwordObj.getAuthCmd() % 'make install'] 1673 else: 1674 return [self.configure(bClassDriver), 1675 'make clean', 1676 'make', 1677 self.passwordObj.getAuthCmd() % 'make install'] 1678 1679 def get_distro_ver_data(self, key, default=None, distro_ver=None): 1680 try: 1681 if distro_ver: 1682 return self.distros[self.distro_name]['versions'][distro_ver].get(key, None) or \ 1683 self.distros[self.distro_name].get(key, None) or default 1684 else: 1685 return self.distros[self.distro_name]['versions'][self.distro_version].get(key, None) or \ 1686 self.distros[self.distro_name].get(key, None) or default 1687 except KeyError: 1688 return default 1689 1690 return value 1691 1692 def get_distro_data(self, key, default=None): 1693 try: 1694 return self.distros[self.distro_name].get(key, None) or default 1695 except KeyError: 1696 return default 1697 1698 def get_ver_data(self, key, default=None, distro_ver=None): 1699 try: 1700 if distro_ver: 1701 return self.distros[self.distro_name]['versions'][distro_ver].get(key, None) or default 1702 else: 1703 return self.distros[self.distro_name]['versions'][self.distro_version].get(key, None) or default 1704 1705 except KeyError: 1706 return default 1707 1708 return value 1709 1710 def get_dependency_data(self, dependency, supported_distro_vrs=None): 1711 dependency_cmds = self.get_ver_data( 1712 "dependency_cmds", {}, supported_distro_vrs) 1713 dependency_data = dependency_cmds.get(dependency, {}) 1714 packages = dependency_data.get('packages', []) 1715 commands = dependency_data.get('commands', []) 1716 return packages, commands 1717 1718 def get_dependency_commands(self): 1719 dd = list(self.dependencies.keys()) 1720 dd.sort() 1721 commands_to_run = [] 1722 packages_to_install = [] 1723 overall_commands_to_run = [] 1724 for d in dd: 1725 include = False 1726 for opt in self.dependencies[d][1]: 1727 if self.selected_options[opt]: 1728 include = True 1729 if include: 1730 pkgs, cmds = self.get_dependency_data(d) 1731 1732 if pkgs: 1733 for p in pkgs: 1734 if not p in packages_to_install: 1735 packages_to_install.append(p) 1736 1737 if cmds: 1738 commands_to_run.extend(cmds) 1739 1740 package_mgr_cmd = self.get_distro_ver_data('package_mgr_cmd') 1741 1742 overall_commands_to_run.extend(commands_to_run) 1743 1744 if package_mgr_cmd: 1745 packages_to_install = ' '.join(packages_to_install) 1746 overall_commands_to_run.append(utils.cat(package_mgr_cmd)) 1747 1748 if not overall_commands_to_run: 1749 log.error("No cmds/pkgs") 1750 1751 return overall_commands_to_run 1752 1753 def distro_known(self): 1754 return self.distro != DISTRO_UNKNOWN and self.distro_version != DISTRO_VER_UNKNOWN 1755 1756 def distro_supported(self): 1757 if self.mode == MODE_INSTALLER: 1758 return self.distro != DISTRO_UNKNOWN and self.distro_version != DISTRO_VER_UNKNOWN and self.get_ver_data('supported', False) 1759 else: 1760 return True # For docs (manual install) 1761 1762 def count_num_required_missing_dependencies(self): 1763 num_req_missing = 0 1764 for d, desc, opt in self.missing_required_dependencies(): 1765 num_req_missing += 1 1766 return num_req_missing 1767 1768 def count_num_optional_missing_dependencies(self): 1769 num_opt_missing = 0 1770 for d, desc, req, opt in self.missing_optional_dependencies(): 1771 num_opt_missing += 1 1772 return num_opt_missing 1773 1774 # missing req. deps for selected components 1775 def missing_required_dependencies(self): 1776 for comp in self.components[self.selected_component][1]: 1777 if self.selected_options[comp]: # if the component was selected 1778 # dependencies for this component 1779 for dep in self.options[comp][2]: 1780 # Is it required dependency? 1781 if self.dependencies[dep][DEPENDENCY_REQUIRED_INDEX]: 1782 # Is it not already installed? 1783 if not self.have_dependencies[dep]: 1784 log.debug("Missing required dependency: %s" % dep) 1785 yield dep, self.dependencies[dep][DEPENDENCY_DISPLAY_INDEX], comp 1786 1787 def missing_optional_dependencies(self): 1788 for comp in self.components[self.selected_component][1]: 1789 if self.selected_options[comp]: # if the component was selected 1790 # dependencies for this component 1791 for dep in self.options[comp][2]: 1792 # Is it optional dependency? 1793 if not self.dependencies[dep][DEPENDENCY_REQUIRED_INDEX]: 1794 # Is it not already installed? 1795 if not self.have_dependencies[dep]: 1796 log.debug("Missing optional dependency: %s" % dep) 1797 yield dep, self.dependencies[dep][DEPENDENCY_DISPLAY_INDEX], self.dependencies[dep][0], comp 1798 1799 def select_options(self, answer_callback): 1800 num_opt_missing = 0 1801 # not-required options 1802 for opt in self.components[self.selected_component][1]: 1803 if opt.find("gui_") != -1 and opt.find(self.ui_toolkit) == -1: 1804 continue 1805 if not self.options[opt][0]: # not required 1806 default = 'y' 1807 1808 if not self.selected_options[opt]: 1809 default = 'n' 1810 1811 self.selected_options[opt] = answer_callback( 1812 opt, self.options[opt][1], default) 1813 1814 if self.selected_options[opt]: # only for options that are ON 1815 for d in self.options[opt][2]: # dependencies 1816 if not self.have_dependencies[d]: # missing dependency 1817 log.debug("Missing optional dependency: %s" % d) 1818 num_opt_missing += 1 1819 1820 return num_opt_missing 1821 1822 def check_wget(self): 1823 if utils.which("wget"): 1824 return True 1825 else: 1826 log.debug("wget is not installed") 1827 return False 1828 1829 def check_avahi_utils(self): 1830 if utils.which("avahi-browse"): 1831 return True 1832 else: 1833 log.debug("avahi-browse is not installed") 1834 return False 1835 1836 ''' 1837 def check_passwd_util(self): 1838 if utils.which("gksu"): 1839 return True 1840 elif utils.which("kdesu"): 1841 return True 1842 elif utils.which("kdesudo"): 1843 return True 1844 else: 1845 log.debug("GUI password gksu/kdesu/kdesudo utility is not installed") 1846 return False''' 1847 1848 def run_pre_install(self, callback=None, distro_ver=None): 1849 pre_cmd = self.get_distro_ver_data('pre_install_cmd', None, distro_ver) 1850 log.debug(pre_cmd) 1851 if pre_cmd: 1852 x = 1 1853 for cmd in pre_cmd: 1854 status, output = utils.run(cmd, self.passwordObj) 1855 1856 if status != 0: 1857 log.warn("An error occurred running '%s'" % cmd) 1858 1859 if callback is not None: 1860 callback(cmd, "Pre-install step %d" % x) 1861 1862 x += 1 1863 1864 return True 1865 1866 else: 1867 return False 1868 1869 def run_pre_depend(self, callback=None, distro_ver=None): 1870 pre_cmd = self.get_distro_ver_data('pre_depend_cmd', None, distro_ver) 1871 log.debug(pre_cmd) 1872 if pre_cmd: 1873 x = 1 1874 for cmd in pre_cmd: 1875 status, output = utils.run(cmd, self.passwordObj) 1876 if any(['yum' in cmd, 'zypper' in cmd, 'dnf' in cmd, 'pacman' in cmd]): 1877 if status == 1: 1878 log.warn("An error occurred running '%s'" % cmd) 1879 else: 1880 if status != 0: 1881 log.warn("An error occurred running '%s'" % cmd) 1882 1883 if callback is not None: 1884 callback(cmd, "Pre-depend step %d" % x) 1885 1886 x += 1 1887 1888 def run_post_depend(self, callback=None, distro_ver=None): 1889 post_cmd = self.get_distro_ver_data( 1890 'post_depend_cmd', None, distro_ver) 1891 log.debug(post_cmd) 1892 if post_cmd: 1893 x = 1 1894 for cmd in post_cmd: 1895 status, output = utils.run(cmd, self.passwordObj) 1896 1897 if status != 0: 1898 log.warn("An error occurred running '%s'" % cmd) 1899 1900 if callback is not None: 1901 callback(cmd, "Post-depend step %d" % x) 1902 1903 x += 1 1904 1905 def run_scanjet_depend(self, callback=None, distro_ver=None): 1906 from base.sixext import PY3 1907 if PY3: 1908 scanjet_cmd = self.get_distro_ver_data('scanjet_py3_depend_cmd', None, distro_ver) 1909 else: 1910 scanjet_cmd = self.get_distro_ver_data('scanjet_depend_cmd', None, distro_ver) 1911 log.debug(scanjet_cmd) 1912 if scanjet_cmd: 1913 x = 1 1914 #log.info("x is %d"%x) 1915 for cmd in scanjet_cmd: 1916 #log.info("cmd is %s"%cmd) 1917 if callback is not None: 1918 callback(cmd, "Scanjet-depend step %d" % x) 1919 status, output = utils.run(cmd, self.passwordObj) 1920 #log.info("status is %d"%status) 1921 if status !=0: 1922 log.warn("Failed to install this Scanjet dependency package. Some Scanjet features will not work.") 1923 #if callback is not None: 1924 #callback(cmd, "Scanjet-depend step %d" % x) 1925 1926 x += 1 1927 '''if status !=0: 1928 sys.exit(0)''' 1929 1930 def pre_build(self, distro_ver=None): 1931 cmds = [] 1932 if self.get_distro_ver_data('fix_ppd_symlink', False, distro_ver): 1933 cmds.append(self.passwordObj.getAuthCmd() % 1934 'python ./installer/fix_symlink.py') 1935 1936 return cmds 1937 1938 def run_pre_build(self, callback=None, distro_ver=None): 1939 x = 1 1940 for cmd in self.pre_build(distro_ver): 1941 status, output = utils.run(cmd, self.passwordObj) 1942 if callback is not None: 1943 callback(cmd, "Pre-build step %d" % x) 1944 1945 x += 1 1946 1947 def run_post_build(self, callback=None, distro_ver=None): 1948 x = 1 1949 for cmd in self.post_build(distro_ver): 1950 status, output = utils.run(cmd, self.passwordObj) 1951 if callback is not None: 1952 callback(cmd, "Post-build step %d" % x) 1953 1954 x += 1 1955 1956 def post_build(self, distro_ver=None): 1957 cmds = [] 1958 # Reload DBUS configuration if distro supports it and PolicyKit 1959 # support installed 1960 if self.reload_dbus and self.selected_options['policykit']: 1961 cmds.append(self.passwordObj.getAuthCmd() % 1962 "sh /usr/local/etc/rc.d/dbus reload") 1963 log.debug("Will reload DBUS configuration for PolicyKit support") 1964 1965 # Kill any running hpssd.py instance from a previous install 1966 pid_list = get_ps_pid(['hp-systray', 'hpssd']) 1967 1968 kill_cmd = utils.which("kill", True) 1969 for pid in pid_list: 1970 log.debug("Found %s for %s process" % (pid, pid_list[pid])) 1971 kill = kill_cmd + " %s" % pid 1972 cmds.append(self.passwordObj.getAuthCmd() % kill) 1973 1974 return cmds 1975 1976 def remove_soT(self): 1977 #log.info("\n Clearing unnecessary sos: ") 1978 run_cmd = 'rm -rf .libs/libhpipp.so.0.0.1T .libs/libsane-hpaio.so.1.0.0T .libs/libhpmud.so.0.0.6T .libs/hpmudext.soT .libs/cupsext.soT' 1979 cmd = self.passwordObj.getAuthCmd() % run_cmd 1980 #run_cmd.append(self.passwordObj.getAuthCmd() % "rm -rf .libs/libhpipp.so.0.0.1T .libs/libsane-hpaio.so.1.0.0T .libs/libhpmud.so.0.0.6T .libs/hpmudext.soT .libs/cupsext.soT") 1981 #self.passwordObj.getAuthCmd() % run_cmd 1982 status, output = utils.run(cmd, self.passwordObj) 1983 1984 def remove_hplip(self, callback=None): 1985 failed = True 1986 hplip_remove_cmd = self.get_distro_ver_data('hplip_remove_cmd') 1987 if hplip_remove_cmd: 1988 if callback is not None: 1989 callback(hplip_remove_cmd, "Removing old HPLIP version") 1990 1991 status, output = utils.run(hplip_remove_cmd, self.passwordObj) 1992 1993 if status == 0: 1994 self.hplip_present = self.check_hplip() 1995 1996 if not self.hplip_present: 1997 failed = False 1998 1999 return failed 2000 2001 def check_password(self): 2002 self.passwordObj.clearPassword() 2003 if self.passwordObj.getPassword() == "": 2004 return False 2005 else: 2006 return True 2007 2008 # PLUGIN HELPERS 2009 2010 def isErrorPage(self, page): 2011 """ 2012 Example code from David Mertz' Text Processing in Python. 2013 Released in the Public Domain. 2014 """ 2015 err_score = 0.0 2016 2017 for pat, prob in list(err_pats.items()): 2018 if err_score > 0.9: 2019 break 2020 if re.search(pat, page): 2021 err_score += prob 2022 2023 log.debug("File error page score: %f" % (err_score)) 2024 2025 return err_score > 0.50 2026 2027 def validate_disto(self): 2028 if self.distro != DISTRO_UNKNOWN: 2029 return True 2030 else: 2031 return True 2032 2033 def validate_distro_version(self): 2034 if self.validate_disto(): 2035 for vers in self.distros[self.distro_name]['versions']: 2036 if self.distro_version == vers: 2037 return True 2038 2039 return False 2040 2041 def is_auto_installer_support(self, distro_version=DISTRO_VER_UNKNOWN): 2042 if not self.distro_name: 2043 self.get_distro() 2044 try: 2045 self.distro_name = self.distros_index[self.distro] 2046 except KeyError: 2047 log.debug("Auto installation is not supported as Distro Name can't find for distro index [%d]." % ( 2048 self.distro)) 2049 return False 2050 2051 if distro_version == DISTRO_VER_UNKNOWN: 2052 distro_version = self.distro_version 2053 2054 if self.distro != DISTRO_UNKNOWN and distro_version != DISTRO_VER_UNKNOWN and self.get_ver_data('supported', False, distro_version): 2055 log.debug("Auto installation is supported for Distro =%s version =%s " % ( 2056 self.distro_name, distro_version)) 2057 return True 2058 else: 2059 log.debug("Auto installation is not supported for Distro =%s version =%s " % ( 2060 self.distro_name, distro_version)) 2061 return False 2062 2063 # Uninstalls the HPLIP package. 2064 # Input: 2065 # mode --> INTERACTIVE_MODE, GUI_MODE 2066 # 2067 # Output: 2068 # result --> returns True on success. 2069 def uninstall(self, mode=INTERACTIVE_MODE, callback=None): 2070 checkSudo = False 2071 if os.getuid() != 0: 2072 checkSudo = True 2073# log.error("To run 'hp-uninstall' utility, you must have root privileges.") 2074# return False 2075 2076 home_dir = sys_conf.get("dirs", "home", "") 2077 version = sys_conf.get("hplip", "version", "0.0.0") 2078 if home_dir == "": 2079 log.error("HPLIP is not installed.") 2080 return False 2081 2082 if mode != NON_INTERACTIVE_MODE: 2083 ok, choice = tui.enter_choice( 2084 "\nAre you sure to uninstall HPLIP-%s (y=yes, n=no*)?:" % version, ['y', 'n'], 'n') 2085 if not ok or choice == 'n': 2086 return False 2087 2088 hplip_remove_cmd = self.get_distro_data('hplip_remove_cmd') 2089 log.debug("hplip_remove_cmd =%s " % hplip_remove_cmd) 2090 # read conf file to enter into installed dir 2091 log.info("Starting uninstallation...") 2092 2093 plugin_state = sys_state.get( 2094 'plugin', 'installed', PLUGIN_NOT_INSTALLED) 2095 2096 # check systray is running? 2097 status, output = utils.Is_Process_Running('hp-systray') 2098 if status is True: 2099 if mode != NON_INTERACTIVE_MODE: 2100 ok, choice = tui.enter_choice( 2101 "\nSome HPLIP applications are running. Press 'y' to close and proceed or Press 'n' to quit uninstall (y=yes*, n=no):", ['y', 'n'], 'y') 2102 if not ok or choice == 'n': 2103 log.info( 2104 "Quiting HPLIP unininstallation. Close application(s) manually and run again.") 2105 return False 2106 2107 # Kill any running hpssd.py instance from a previous install 2108 pid_list = get_ps_pid(['hp-systray']) 2109 kill_cmd = utils.which("kill", True) 2110 for pid in pid_list: 2111 log.debug("Found %s for %s process" % (pid, pid_list[pid])) 2112 kill = kill_cmd + " %s" % pid 2113 sts, out = utils.run(kill) 2114 log.debug("sts =%s out=%s" % (sts, out)) 2115 2116 toolbox_status, output = utils.Is_Process_Running('hp-toolbox') 2117 systray_status, output = utils.Is_Process_Running('hp-systray') 2118 if toolbox_status is True or systray_status is True: 2119 log.error( 2120 "Failed to close HP-Toolbox/HP-Systray. Close manually and run hp-uninstall again.") 2121 return False 2122 2123 if hplip_remove_cmd: 2124 User_exit, Is_pkg_mgr_running = self.close_package_managers() 2125 if User_exit: 2126 sys.exit(0) 2127 self.remove_hplip(callback) 2128 2129 # removing .hplip directory 2130 cmd = 'find /home -name .hplip' 2131 if checkSudo: 2132 cmd = self.passwordObj.getAuthCmd() % cmd 2133 2134 status, output = utils.run(cmd, self.passwordObj) 2135 if output is not None: 2136 for p in output.splitlines(): 2137 if p.find("find:") != -1: 2138 continue 2139 2140 utils.remove(p, self.passwordObj, checkSudo) 2141 2142 # Removing Security profiles/policies 2143 package_st = self.security_package_status() 2144 if package_st[1]: 2145 log.debug("Removing Security Profiles") 2146 [utils.remove(f, self.passwordObj, checkSudo) 2147 for f in SEC_DICT[package_st[0]][1]] 2148 2149 # remove the binaries and libraries 2150 pat = re.compile(r"""(\S.*)share\/hplip""") 2151 base = pat.match(home_dir) 2152 usrbin_dir = None 2153 if base is not None: 2154 usrbin_dir = base.group(1) + "bin/" 2155 usrlib_dir = base.group(1) + "lib/" 2156 cnt = 0 2157 BINS_LIST_FULL = utils.expandList(BINS_LIST, usrbin_dir) 2158 while cnt < len(BINS_LIST_FULL): 2159 utils.remove(BINS_LIST_FULL[cnt], self.passwordObj, checkSudo) 2160 cnt += 1 2161 2162 cnt = 0 2163 LIBS_LIST_FULL = utils.expandList(LIBS_LIST, usrlib_dir) 2164 while cnt < len(LIBS_LIST_FULL): 2165 utils.remove(LIBS_LIST_FULL[cnt], self.passwordObj, checkSudo) 2166 cnt += 1 2167 2168 remove_plugins = False 2169 if mode != NON_INTERACTIVE_MODE and plugin_state != PLUGIN_NOT_INSTALLED: 2170 ok, choice = tui.enter_choice( 2171 "\nDo you want to remove HP proprietary plug-ins (y=yes*, n=no)?:", ['y', 'n'], 'y') 2172 if ok and choice == 'y': 2173 remove_plugins = True 2174 else: 2175 remove_plugins = True 2176 2177 # removing HPLIP installed directories/files 2178 if remove_plugins is False: 2179 HPLIP_LIST_FULL = utils.expandList(HPLIP_LIST, home_dir) 2180 else: 2181 HPLIP_LIST_FULL = [] 2182 cnt = 0 2183 while cnt < len(HPLIP_LIST_FULL): 2184 utils.remove(HPLIP_LIST_FULL[cnt], self.passwordObj, checkSudo) 2185 cnt += 1 2186 2187 # removing ppd directory 2188 ppd_dir = sys_conf.get('dirs', 'ppd', '') 2189 if ppd_dir: 2190 utils.remove(ppd_dir, self.passwordObj, checkSudo) 2191 2192 # removing configuration files 2193 FILES_LIST_FULL = utils.expandList(FILES_LIST) 2194 cnt = 0 2195 while cnt < len(FILES_LIST_FULL): 2196 utils.remove(FILES_LIST_FULL[cnt], self.passwordObj, checkSudo) 2197 cnt += 1 2198 2199 # removing Rules files 2200 RULES_LIST_FULL = utils.expandList(RULES_LIST, '/etc/udev/rules.d') 2201 for fl in RULES_LIST_FULL: 2202 utils.remove(fl, self.passwordObj, checkSudo) 2203 2204 RULES_LIST_FULL = utils.expandList(RULES_LIST, '/lib/udev/rules.d') 2205 for fl in RULES_LIST_FULL: 2206 utils.remove(fl, self.passwordObj, checkSudo) 2207 2208 # removing (unused) hplip folder from other location 2209 cmd = 'find /usr -type d -name hplip' 2210 cmd = self.passwordObj.getAuthCmd() % cmd 2211 status, output = utils.run(cmd, self.passwordObj, checkSudo) 2212 if status == 0: 2213 hplip_folders = output.splitlines() 2214 for hplip_d in hplip_folders: 2215 if hplip_d != home_dir: 2216 utils.remove(hplip_d, self.passwordObj, checkSudo) 2217 2218 # removing all hplip extension libraries 2219 for ext_f in HPLIP_EXT_LIST: 2220 if ext_f: 2221 cmd = 'find /usr -type f -name %s -delete' % ext_f 2222 cmd = self.passwordObj.getAuthCmd() % cmd 2223 status, output = utils.run(cmd, self.passwordObj, checkSudo) 2224 if status != 0: 2225 log.warn( 2226 "Failed to delete %s library [%s]" % (ext_f, output)) 2227 2228 # removing Plug-in files 2229 if remove_plugins == True: 2230 cnt = 0 2231 PLUGIN_LIST_FULL = utils.expandList(PLUGIN_LIST, home_dir) 2232 while cnt < len(PLUGIN_LIST_FULL): 2233 utils.remove(PLUGIN_LIST_FULL[cnt], 2234 self.passwordObj, checkSudo) 2235 cnt += 1 2236 2237 cnt = 0 2238 PLUGIN_STATE_FULL = utils.expandList(PLUGIN_STATE) 2239 while cnt < len(PLUGIN_STATE_FULL): 2240 utils.remove(PLUGIN_STATE_FULL[ 2241 cnt], self.passwordObj, checkSudo) 2242 cnt += 1 2243 2244 utils.remove(home_dir, self.passwordObj, checkSudo) 2245 2246 # removing HPLIP uninstall link 2247 if usrbin_dir is not None: 2248 hp_uninstall = usrbin_dir + "hp-unistall" 2249 utils.remove(hp_uninstall, self.passwordObj, checkSudo) 2250 2251 log.info("HPLIP uninstallation is completed") 2252 return True 2253 2254 # close_package_managers() closes the package managers, if running 2255 # Input: 2256 # MODE --> INTERACTIVE_MODE, GUI_MODE (GUI_MODE is not yet supported). 2257 # Output: 2258 # User_exit (bool) --> returns True, if user quits. 2259 # --> returns False, if user doesn't select quit option. 2260 # Is_pkg_mgr_running (bool) -->returns False, if no packages are running at end of function. 2261 # -->returns True, if some package(s) is(are) running at end of function. 2262 def close_package_managers(self, MODE=INTERACTIVE_MODE): 2263 User_exit = False 2264 Is_pkg_mgr_running = False 2265 pid, cmdline = utils.check_pkg_mgr(self.package_mgrs) 2266 while pid: 2267 if MODE == INTERACTIVE_MODE: 2268 ok, user_input = tui.enter_choice( 2269 "A package manager '%s' appears to be running. Please quit the package manager and press enter to continue (i=ignore, r=retry*, f=force, q=quit) :" % cmdline, ['i', 'r', 'q', 'f'], 'r') 2270 if not ok: 2271 return True, True # --> User_exit = True , Is_pkg_mgr_running =True 2272 if user_input == 'i': 2273 log.warn( 2274 "Ignoring running package manager. Some package operations may fail.") 2275 break 2276 if user_input == 'f': 2277 ok, ans = tui.enter_yes_no( 2278 "\nForce quit of package manager '%s'" % cmdline, 'y') 2279 if not ok: 2280 return True, True # --> User_exit = True , Is_pkg_mgr_running =True 2281 if ans: 2282 cmd = self.passwordObj.getAuthCmd() % ("kill %s" % pid) 2283 status, output = utils.run(cmd, self.passwordObj) 2284 if status != 0: 2285 log.error( 2286 "Failed to kill process. You may need to manually quit the program.") 2287 else: 2288 log.error("GUI is not yet supported") 2289 # TBD 2290 break 2291 pid, cmdline = utils.check_pkg_mgr(self.package_mgrs) 2292 2293 if pid: # checking for still running package managers 2294 Is_pkg_mgr_running = True 2295 2296 return User_exit, Is_pkg_mgr_running 2297 2298 # add_groups_to_user() 2299 # Input: 2300 # missing_user_groups (string) --> Contains only missing groups, to show to user. 2301 # missing_user_groups_cmd (string) --> command as per distro.dat (i.e. add_user_to_group) 2302 # mode --> INTERACTIVE_MODE, GUI_MODE (GUI_MODE is not yet supported). 2303 # Output: 2304 # ret_val (bool) --> returns True, if succeeded to add groups to user. 2305 # --> returns False, if Failed to add groups to user. 2306 # Move to utils 2307 def add_groups_to_user(self, missing_user_groups, missing_user_groups_cmd, mode=INTERACTIVE_MODE): 2308 ret_val = False 2309 if mode == INTERACTIVE_MODE: 2310 if not missing_user_groups or not missing_user_groups_cmd: 2311 return False 2312 2313 ok, user_input = tui.enter_choice( 2314 "Do you want to add missing groups %s to user?(y=yes*, n=no)" % missing_user_groups, ['y', 'n'], 'y') 2315 if ok and user_input == 'y': 2316 usermod_path = utils.which('usermod', True) 2317 if usermod_path: 2318 cmd = "%s %s %s" % ( 2319 usermod_path, missing_user_groups_cmd, prop.username) 2320 cmd = self.passwordObj.getAuthCmd() % cmd 2321 log.debug("cmd = %s" % cmd) 2322 sts, out = utils.run(cmd, self.passwordObj) 2323 if sts == 0: 2324 ret_val = True 2325 else: 2326 log.error("usermod command not found.") 2327 else: 2328 log.info(log.bold("Please add %s groups to %s user" % 2329 (missing_user_groups, prop.username))) 2330 else: 2331 log.error("GUI is not yet supported") 2332 # TBD 2333 return ret_val 2334 2335 # disable_SELinux() 2336 # Input: 2337 # MODE --> INTERACTIVE_MODE, GUI_MODE (GUI_MODE is not yet supported). 2338 # Output: 2339 # ret_val (bool) --> returns True, if succeeded to disable SELinux. 2340 # --> returns False, if Failed to disable SELinux. 2341 2342 def disable_SELinux(self, mode=INTERACTIVE_MODE): # Move to utils 2343 ret_val = False 2344 SELinux_file = '/etc/selinux/config' 2345 if mode == INTERACTIVE_MODE: 2346 ok, user_input = tui.enter_choice( 2347 "SELinux is currently enabled in your system. Device may not work properly. Do you want to disable SELinux?(y=yes, n=no*)", ['y', 'n'], 'n') 2348 if ok and user_input != 'n': 2349 if not os.path.exists(SELinux_file): 2350 log.debug("File %s is not found" % SELinux_file) 2351 return False 2352 cmd = self.passwordObj.getAuthCmd() % ( 2353 "vi -c %s/enforcing$/disabled -c wq " + SELinux_file) 2354 log.debug("cmd= %s " % cmd) 2355 sts, out = utils.run(cmd, self.passwordObj) 2356 if sts == 0: 2357 ret_val = True 2358 if os.path.exists('/selinux/enforce'): 2359 cmd = "echo 0 >/selinux/enforce" 2360 cmd = self.passwordObj.getAuthCmd() % cmd 2361 log.debug("cmd= %s " % cmd) 2362# utils.run(cmd, self.passwordObj) 2363 os_utils.execute(cmd) 2364 2365 else: 2366 log.error("GUI is not yet supported") 2367 # TBD 2368 2369 return ret_val 2370 2371 # Move to core_install 2372 def install_missing_dependencies(self, mode=INTERACTIVE_MODE, required_dependencies=[], optional_dependencies=[], missing_cmd=[]): 2373 package_mgr_cmd = self.get_distro_ver_data('package_mgr_cmd') 2374 pre_depend_cmd = self.get_distro_ver_data('pre_depend_cmd') 2375 overall_install_cmds = {} 2376 2377 if len(required_dependencies): 2378 for packages_to_install in required_dependencies: 2379 if package_mgr_cmd: 2380 overall_install_cmds[ 2381 packages_to_install] = utils.cat(package_mgr_cmd) 2382 else: 2383 overall_install_cmds[ 2384 packages_to_install] = packages_to_install 2385 2386 if len(optional_dependencies): 2387 for packages_to_install in optional_dependencies: 2388 if package_mgr_cmd: 2389 overall_install_cmds[ 2390 packages_to_install] = utils.cat(package_mgr_cmd) 2391 else: 2392 overall_install_cmds[ 2393 packages_to_install] = packages_to_install 2394 2395 if len(overall_install_cmds) == 0 and len(missing_cmd) == 0: 2396 log.info("No missing dependencies") 2397 return 0 2398 2399 if mode == INTERACTIVE_MODE: 2400 ok, user_input = tui.enter_choice( 2401 "Do you want to update repository and Install missing/incompatible packages. (a=install all*, c=custom_install, s=skip):", ['a', 'c', 's'], 'a') 2402 if not ok or user_input == 'q': 2403 return 1 2404 elif user_input == 's': 2405 log.info( 2406 log.bold("Install manually above missing/incompatible packages.")) 2407 else: 2408 self.close_package_managers() 2409 2410 log.info(log.bold("Updating repository")) 2411 log.info(log.bold('-' * len("Updating repository"))) 2412 if pre_depend_cmd: 2413 for cmd in pre_depend_cmd: 2414 log.info("cmd =%s" % (cmd)) 2415 sts, out = utils.run(cmd, self.passwordObj) 2416 if sts != 0 or "Failed" in out: 2417 log.warn( 2418 "Failed to update Repository, check if any update/installation is running.") 2419 2420 if user_input == 'c': 2421 log.info(log.bold("Installing missing/incompatible packages")) 2422 log.info( 2423 log.bold('-' * len("Installing missing/incompatible packages"))) 2424 for d in overall_install_cmds: 2425 ok, user_input = tui.enter_choice( 2426 "Do you want to install '%s' package?(y=yes*, n=no):" % d, ['y', 'n'], 'y') 2427 if ok and user_input == 'y': 2428 if 'hpaio' in overall_install_cmds[d]: 2429 self.update_hpaio() 2430 else: 2431 log.info("cmd =%s" % overall_install_cmds[d]) 2432 sts, out = utils.run(overall_install_cmds[ 2433 d], self.passwordObj) 2434 if sts != 0 or "Failed" in out: 2435 log.error( 2436 "Failed to install '%s' package, please install manually. " % d) 2437 if 'cups' in d: 2438 if not services.start_service('cups', self.passwordObj): 2439 log.error( 2440 "Failed to start CUPS service. Please start CUPS manually or restart system.") 2441 for cmd in missing_cmd: 2442 ok, user_input = tui.enter_choice( 2443 "Do you want to run '%s' command?(y=yes*, n=no):" % d, ['y', 'n'], 'y') 2444 if ok and user_input == 'y': 2445 sts, out = utils.run(cmd, self.passwordObj) 2446 if sts != 0 or "Failed" in out: 2447 log.error( 2448 "Failed to run '%s' command, please run manually. " % d) 2449 2450 elif user_input == 'a': 2451 log.info(log.bold("Installing Missing/Incompatible packages")) 2452 log.info( 2453 log.bold('-' * len("Installing Missing/Incompatible packages"))) 2454 for d in overall_install_cmds: 2455 if 'hpaio' in overall_install_cmds[d]: 2456 self.update_hpaio() 2457 else: 2458 log.info("cmd =%s" % overall_install_cmds[d]) 2459 sts, out = utils.run(overall_install_cmds[ 2460 d], self.passwordObj) 2461 if sts != 0 or "Failed" in out: 2462 log.error( 2463 "Failed to install '%s' package, please install manually. " % d) 2464 if 'cups' in d: 2465 if not services.start_service('cups', self.passwordObj): 2466 log.error( 2467 "Failed to start CUPS sevice. Please start CUPS manually or restart system.") 2468 for cmd in missing_cmd: 2469 sts, out = utils.run(cmd, self.passwordObj) 2470 if sts != 0 or "Failed" in out: 2471 log.error( 2472 "Failed to run '%s' command, please run manually. " % d) 2473 2474 else: 2475 log.error("GUI is not yet supported..1") 2476 # TBD 2477 2478 return 0 2479