def __uninstall_operation(self, data_to_remove): """ Uninstall Files given in data_to_remove dictionary. :param data_to_remove: Data to remove :type data_to_remove: dict """ file_name = data_to_remove.get('name') destination = format_configuration_path( data_to_remove.get('destination')) try: # Remove installed file if path.isfile(destination): logger.info("Removing file '{0}'".format(file_name)) unlink(destination) elif path.isdir(destination): logger.info("Removing folder '{0}'".format(destination)) rmtree(destination) # Remove shortcut if any shortcut_list = data_to_remove.get('shortcut') if shortcut_list: for shortcut_args in shortcut_list: sc_name = shortcut_args.get('name') self.remove_shortcut(sc_name) except Exception as sc_exception: error_msg = "Uninstall error of {0} ! ({1})".format( file_name, sc_exception) logger.error(error_msg) self.error('SetupManagerException', error_msg)
def get_installed_packages(self): """ Get all installed packages using "pip freeze" command """ logger.info("Getting list of installed python packages...") import pip for package_info in pip.get_installed_distributions(): self.installed_packages.update( {package_info.project_name: package_info.version})
def load_profiles(self): """ Loads all Profiles from JSON to Structure """ for p in os.listdir(CONFIG_PROFILES_DIR): profile = path.abspath(path.join(CONFIG_PROFILES_DIR, p)) if p.endswith('.json'): self.profiles[p.replace('.json', '')] = Loader.load(profile) else: logger.info('Profile ``{0}`` seems not to be JSON format, ' 'as it MUST ends with `.json` extension'.format(p))
def run(self): """ Runs the Setup process. """ logger.info('{0}ing {1} profile(s) ...'.format(self.execute.capitalize(), self.setup_names)) # The order is important ! # As some binaries might be dependencies for Python package(s) such as dll, ... self.bin_manager.run() self.pypi_manager.run() self.equipment_manager.run() self.fs_manager.run()
def __init__(self, options): """ Constructor :param options: An instance of settings options :type options: argparse.Namespace """ # if not self.is_root: # raise setup_exception(ManagerBase.InstallationException, # 'Please execute this script with super user privileges (sudo).') # Instantiation self.profiles = {} self.setup = {} self.setup_names = tuple(options.profile) self.execute = str(options.execute).strip() # Loading all known profiles (from configs/profiles) self.load_profiles() # Gathering all Profile(s) data according command-line arguments self.gather_profiles() # looking for cache folder path if provided in Environment or default one self.cache = format_configuration_path(os.environ.get('ACS_CACHE_FOLDER')) or DEFAULT_CACHE_FOLDER if self.cache: logger.info('Your Cache root directory location is `{0}`'.format(self.cache)) artifacts_location = self.setup.get('artifacts_location', ManagerBase.DEFAULT_REPO_BASE) # Assigning common Manager keyword arguments mgr_options = dict(execute=self.execute, repo=artifacts_location, cache=self.cache) # Casting all sets into list (mutable) self.binaries_data = list(self.setup.get('binaries', [])) self.equipments_data = list(self.setup.get('equipments', [])) self.pypi_data = list(self.setup.get('pypi', {})) self.files_data = list(self.setup.get('files', [])) # Create all required Managers self.bin_manager = BinaryManager(data=self.binaries_data, **mgr_options) self.equipment_manager = EquipmentManager(data=self.equipments_data, **mgr_options) self.pypi_manager = PyPiManager(data=self.pypi_data, **mgr_options) self.fs_manager = FsManager(data=self.files_data, **mgr_options)
def setup_proxy(environ=None, http=DEFAULT_PROXY_SETTINGS['http'], https=DEFAULT_PROXY_SETTINGS['http'], reset=False): """ Sets the proxy environment variables, if not already set. Or reset it (for this current python session) :param environ: (optional) :type environ: dict :param http: (optional) :type http: str :param https: (optional) :type https: str :param reset: if True all PROXIES settings are disabled for the session. :type reset: bool """ environ = environ or os.environ if reset: logger.info("Resetting HTTP_PROXY...") environ["NO_PROXY"] = ".intel.com" if "HTTP_PROXY" in environ: del environ["HTTP_PROXY"] if "HTTPS_PROXY" in environ: del environ["HTTPS_PROXY"] else: if 'HTTP_PROXY' not in environ: logger.info("Setting HTTP_PROXY to " + http) environ['HTTP_PROXY'] = http else: logger.info("HTTP Proxy Already Set: " + environ['HTTP_PROXY']) if 'HTTPS_PROXY' not in environ: logger.info("Setting HTTPS_PROXY to " + https) environ['HTTPS_PROXY'] = https else: logger.info("HTTPS Proxy Already Set: " + environ['HTTPS_PROXY'])
def is_python_supported(self): """ Check if current python version is supported :return: True if supported else False :rtype: bool """ logger.info("Checking python version ...") logger.info("Python minimal version: {0} - maximum version: {1}".format(PYTHON_MIN_VERSION_STR, PYTHON_MAX_VERSION_STR)) logger.info("\nCurrent python version: {0}\n".format(platform.python_version())) if sys.hexversion < PYTHON_MIN_VERSION_HEX or sys.hexversion > PYTHON_MAX_VERSION_STR: return_code = False else: return_code = True return return_code
def format_pip_command(self, requirement, use_wheel=True, download_cache=False, find_links=True, index_url=True, upgrade=True): """ Formats a Pip command arguments as a list to be directly consumes by our internal :meth:`run_command` :param requirement: The package name or a requirement file path requirement guess: str, unicode :param use_wheel: If set to False, pip won't lookup for wheel packages (.whl) :type use_wheel: bool :param download_cache: If set to True, all downloaded packages are stored in a cache folder :type download_cache: bool :param find_links: If set to True, the specified "pypi" link or the default one is set as "--find-links" Pip option :type find_links: bool :param index_url: If set to True, the specified "pypi" link or the default one is set as "--index-url" Pip option :type index_url: bool :param upgrade: If set to True, an upgrade to the newest available version is attempted even if the package is already installed :type upgrade: bool :return: The Pip command arguments as a list :rtype: list """ command_args = ['pip'] if self.session.os == OsSupport.windows: py_exe = path.dirname(self.session.python.executable_path) # Virtualenv case if py_exe.lower().endswith('scripts'): pip_exe = absjoin(py_exe, "pip") else: pip_exe = absjoin(py_exe, "Scripts", "pip") command_args = [pip_exe] command_args.append(self.execute) cap_action = self.execute.capitalize() # If the `requirement` exists and is a file, then we've got a requirement file if requirement and path.isfile(requirement): command_args.append('--requirement') info_msg = ("{0}ing python packages based on pip" "requirement file : {1} ...").format( cap_action, requirement) # Else we've got a package name only else: info_msg = "{0}ing python package {1} using pip ...".format( cap_action, requirement) command_args.append(requirement) if self.execute == "install": command_args.append( '--{0}use-wheel'.format('' if use_wheel else 'no-')) if upgrade: command_args.append('--upgrade') if download_cache: command_args.append('--download-cache') command_args.append(self.cache) if find_links or index_url: command_args.append('--find-links') command_args.append(self.repo) if index_url: command_args.append('--index-url') command_args.append(self.repo) else: command_args.append('--no-index') command_args.append('--cert') command_args.append('"{0}"'.format(CONFIG_PIP_CERT_FILE)) else: command_args.append('--yes') print(info_msg) logger.info(info_msg) return command_args
def ensure_pip_wheel(self): """ Configures all requirements for allowing use of :mod:`pip` module. Ensures Pip version is minimum 1.5.6+ :raise: SetupManagerException @Todo: Sometimes, especially on Unix platform, when pip was installed from System packages Manager such as `apt-get install python-pip`, then trying to install it from `get_pip.py` script will cause troubles in the system path, as the package might not be found from the Command line Terminal! Therefore, strange errors like: "/bin/sh: pip not found!" could occur This is due (but more reasons might produce this strange behavior) to remaining "pip" files in /usr/local/lib/python2.7/dist-packages 2 directories: * pip * pip-1.5.6.dist-info @solution: look for those patterns in appropriated folders before ensuring pip installation. If match(es) is/are found, remove it/them! """ def error_handler(this, callback, args): code = callback(args) if code != 0: msg = 'Error while executing PIP {0}'.format(' '.join(args)) logger.error(msg) this.error(this.SetupManagerException, msg) command_args = ['--index-url', self.repo, '--find-links', self.repo] try: import pip import pkg_resources except (ImportError, NameError): logger.info("'pip' module not found !") opts = dict(upgrade=True) if self.PIP_REQUIRED_VERSION: opts['specific_version'] = ">=" + self.PIP_REQUIRED_VERSION error_handler(self, get_pip.main, command_args) import pip try: import pkg_resources except ImportError: import pip._vendor.pkg_resources as pkg_resources # Ensuring All required modules are known from the system sys.modules['pip'] = pip sys.modules['pkg_resources'] = pkg_resources parse_v = pkg_resources.parse_version current_v = self.extract_package_version(pip) if current_v != u'unknown': need2upgrade = parse_v(current_v) < parse_v( self.PIP_MINIMAL_VERSION) else: # Unknown version, therefore we need to upgrade need2upgrade = True if need2upgrade: error_handler(self, get_pip.main, command_args)
def is_os_supported(self): """ Check if current OS version is supported :return: True if supported else False :rtype: bool """ logger.info("Checking OS version ...") logger.info("Supported OS are:") for os_name in SUPPORTED_OS: for os_version in SUPPORTED_OS[os_name]: logger.info("\t{0} {1}".format(os_name, os_version)) logger.info("") current_os_name = platform.system() if 'Windows' in current_os_name: # On Windows, users can install python 32 bits on a 64 bits machine # In this case platform.architecture will return 32 bits as we expect 64 bits. # To avoid that, we check environment variables. For further details refer to: # http://stackoverflow.com/questions/2764356/python-get-windows-os-version-and-architecture current_os_arch = '32bit' if ('x86' in environ.get("PROCESSOR_ARCHITECTURE") and 'AMD64' not in environ.get("PROCESSOR_ARCHITEW6432", "")) else '64bit' current_os_version = platform.release() else: current_os_arch = platform.architecture()[0] current_os_version = " ".join(platform.dist()[:-1]) logger.info("Current OS version: {0} {1} {2}".format(current_os_name, current_os_version, current_os_arch)) if current_os_name in SUPPORTED_OS: current_os_info = "{0} {1}".format(current_os_version, current_os_arch) return_code = any([x for x in SUPPORTED_OS[current_os_name] if current_os_info in x]) else: return_code = False logger.info("") return return_code
def run(self): """ Runs the manager """ if self.data: super(BinaryManager, self).run() win32 = self.session.os == OsSupport.windows is32 = self.session.system.is32bit for b in self.data: binary_dirname = b.split('@')[0].strip() binary_desc = path.abspath( path.join(self.CONFIG_DIR, b.strip() + '.json')) binary = Loader.load(binary_desc) is_binary_installed, binary_installed_path = self.is_executable_present( binary) artifact_location = binary.get('artifacts_location') bin_data = binary.get('windows') if win32 else binary.get( 'linux') if not bin_data: logger.warning( 'Missing configuration file (.json) for binary ' '{0} on {1}'.format(binary_dirname, self.session.os)) continue # Execute pre installation scripts pre_processing_instructions = bin_data.get("pre_{0}".format( self.execute)) post_processing_instructions = bin_data.get("post_{0}".format( self.execute)) # handling Ubuntu direct command form system packages manager. (Apt-get) formatted_cmd = bin_data.get(self.execute) if formatted_cmd is None: logger.info( 'No {0} command provided for binary {1}'.format( self.execute, binary_dirname)) continue if not win32 and formatted_cmd and 'apt-get' in formatted_cmd: if is_binary_installed: info_msg = 'Binary {0} is already {1}ed !'.format( binary_dirname, self.execute) logger.info(info_msg) print(info_msg) continue self.pre_processing(pre_processing_instructions) output_cmd = self.run_command(formatted_cmd) if output_cmd.return_code != 0: error_msg = 'Error while executing {0}'.format( formatted_cmd) self.error('SetupManagerException', error_msg) else: self.post_processing(post_processing_instructions) continue artifact_location = bin_data.get('artifacts_location', artifact_location) if not artifact_location: artifact_location = self.DEFAULT_REPO_BASE # Handling OS arch if is32: bin_arch = bin_data.get('32') else: bin_arch = bin_data.get('64') if not bin_arch: logger.info( 'No 64bits version found for binary {0}'.format( binary_dirname)) logger.info('Looking for 32bits ...') bin_arch = bin_data.get('32') if not bin_arch and win32: logger.warning( 'None artifact found for binary {0} at all!! ' 'Check your Configuration!'.format(binary_dirname)) continue # Handling Python binaries, str.format(), will NOT replace anything if not expected # see Configuration file (.json) bin_arch = bin_arch.format( pyversion=self.session.python.version) binary_name = bin_arch.split('/')[-1:][0] binary['name'] = binary_dirname print("{0}ing binary {1}".format(self.execute.capitalize(), binary_dirname)) if ((self.execute == "install" and is_binary_installed) or (self.execute == "uninstall" and not is_binary_installed)): info_msg = 'Binary {0} is already {1}ed !'.format( binary_dirname, self.execute) logger.info(info_msg) print(info_msg) continue if (self.execute == "uninstall" and is_binary_installed and path.exists(ur'{0}'.format(binary_installed_path))): local_artifact = binary_installed_path else: local_artifact = os.path.join(self.cache, binary_dirname, binary_name) if not os.path.exists(local_artifact): artifact_uri = urljoin(artifact_location, bin_arch) opts = {} # Internal Artifacts location (ACS Artifactory repository) else external (PFT, ...) if not artifact_location.strip() == self.DEFAULT_REPO_BASE: opts['local_location'] = '{0}/{1}'.format( binary_dirname, artifact_uri[len(artifact_location):]) local_artifact = self.download_file(artifact_uri, **opts) if local_artifact: if local_artifact.endswith('.zip'): rootdir, name = path.split(local_artifact) self.unzip(local_artifact, rootdir) zip_info = bin_data.get('zip') if zip_info: local_artifact = path.join(rootdir, zip_info.get('bin')) else: local_artifact = local_artifact.replace( '.zip', '.exe') # Executing pre-processing actions self.pre_processing(pre_processing_instructions) execute_cmd = '' if win32: execute_cmd += 'start /w ' execute_cmd += formatted_cmd.format(bin=r'%s' % local_artifact) logger.info('Executing {1} {0} ...'.format( execute_cmd, self.execute.upper())) output_cmd = self.run_command(execute_cmd) if output_cmd.return_code != 0: error_msg = 'Error while executing {0}'.format( execute_cmd) self.error('SetupManagerException', error_msg) else: # Executing post-processing actions self.post_processing(post_processing_instructions) else: error_msg = "Cannot install binary {0} !".format( binary_name) logger.error(error_msg) self.error('SetupManagerException', error_msg)