From 26730e616e86cbb9a8c4d0f81020221c7b7038b5 Mon Sep 17 00:00:00 2001 From: Javinator9889 Date: Thu, 10 May 2018 19:54:32 +0200 Subject: [PATCH] Version 1.18 - using logging instead of custom Log class --- kernel_upgrader/__init__.py | 117 ++++++++++++------- kernel_upgrader/data_manager/__init__.py | 87 +++++++------- kernel_upgrader/net/DependenciesInstaller.py | 15 ++- kernel_upgrader/net/Downloader.py | 19 +-- kernel_upgrader/net/PageInfo.py | 30 +++-- kernel_upgrader/utils/Singleton.py | 37 ------ kernel_upgrader/utils/__init__.py | 112 ++++-------------- kernel_upgrader/utils/logger.py | 17 +++ kernel_upgrader/values/Constants.py | 81 ++++++------- setup.py | 4 +- version.json | Bin 34 -> 32 bytes 11 files changed, 237 insertions(+), 282 deletions(-) delete mode 100644 kernel_upgrader/utils/Singleton.py create mode 100644 kernel_upgrader/utils/logger.py diff --git a/kernel_upgrader/__init__.py b/kernel_upgrader/__init__.py index cae4b48..f0d2cc0 100644 --- a/kernel_upgrader/__init__.py +++ b/kernel_upgrader/__init__.py @@ -1,17 +1,19 @@ import argparse import time +import logging from .utils import (isRunningLinux, - Log, isUserAdmin, getLinuxVersion, getFreeSpaceAvailable, cleanupSpace, - isNewVersionAvailable + isNewVersionAvailable, + cleanupOldLogs ) from .utils.colors import OutputColors as Colors from .utils.anim import Animation -from .values.Constants import REPO_URL, USAGE, VERSION +from .utils.logger import setup_logging +from .values.Constants import OP_REPO_URL, EXU_USAGE, OP_VERSION, LOG_FILE_PATH, LOG_FILENAME, LOG_COMPILER_FILENAME from .exceptions import (LinuxSystemNotFound, RootPrivilegesNotGiven, raiserModuleNotFound, @@ -25,92 +27,115 @@ __program_name = """Kernel Upgrader for Linux""" __program_description = """Download, compile and install the latest stable kernel for your Linux system. Automate this tool for upgrading your kernel periodically""" -__program_version = "Current running version: " + VERSION + " - " + REPO_URL +__program_version = "Current running version: " + OP_VERSION + " - " + OP_REPO_URL def application(arg): usage = arg.usage + show_version = arg.version + check_kernel_updates = arg.check if usage: - print(USAGE) + print(EXU_USAGE) + elif show_version: + print(__program_version) + elif check_kernel_updates: + if not isRunningLinux(): + raise LinuxSystemNotFound(Colors.FAIL + + "Your OS is not running under a Linux installation. It is not possible" + " to update the kernel" + Colors.ENDC) + else: + from packaging import version + info = Connection() + current_version = getLinuxVersion() + new_version = info.getLatestVersionCode() + if version.parse(current_version) >= version.parse(new_version): + print(Colors.FAIL + "You already have the latest version: " + current_version + Colors.ENDC) + exit(1) + else: + print(Colors.OKGREEN + "There is a new version available: " + Colors.ENDC + Colors.BOLD + new_version + + Colors.ENDC + "\n\nRun this program without \"-c\" (\"--check\") option to upgrade") + exit(0) else: if isNewVersionAvailable(): print(Colors.HEADER + "New version available" + Colors.ENDC + Colors.OKBLUE + " | Download it with pip" " or go to this URL: " - + Colors.ENDC + Colors.UNDERLINE + REPO_URL + Colors.ENDC + "\n") + + Colors.ENDC + Colors.UNDERLINE + OP_REPO_URL + Colors.ENDC + "\n") time.sleep(8) if not isUserAdmin(): raise RootPrivilegesNotGiven(Colors.FAIL + "This application needs root rights in order to work properly." " Run with \"-u\" option to get more information" + Colors.ENDC) else: - __log = Log.instance() + cleanupOldLogs() + setup_logging("kernel_logging", LOG_FILE_PATH + LOG_FILENAME) + setup_logging("compiler_logging", LOG_FILE_PATH + LOG_COMPILER_FILENAME) + __log = logging.getLogger("kernel_logging") animator = Animation(0.1) try: if not isRunningLinux(): - __log.e("OS is not under a Linux installation. Aborting kernel upgrade...") + __log.error("OS is not under a Linux installation. Aborting kernel upgrade...") raise LinuxSystemNotFound(Colors.FAIL + "Your OS is not running under a Linux installation. It is not possible" " to update the kernel" + Colors.ENDC) else: - __log.i("Checking for free space available...") + __log.info("Checking for free space available...") free_space = float(getFreeSpaceAvailable()) if free_space < 20: - __log.e("There is not enough free space available. Current free space (in GB): " - + str(free_space)) - # __log.finish() + __log.error("There is not enough free space available. Current free space (in GB): " + + str(free_space)) raise NotEnoughFreeSpaceAvailable(Colors.FAIL + "There is not enough free space available on " "drive which mounts \"/home\" 20GB are needed " "at least" + Colors.ENDC) - __log.i("There is enough free space available. Current free space: " + str(free_space) + " GB") - __log.i("Starting kernel compiling") - __log.d("Checking versions") + __log.info("There is enough free space available. Current free space: " + str(free_space) + " GB") + __log.info("Starting kernel compiling") + __log.debug("Checking versions") current_version = getLinuxVersion() - __log.i("Current version detected: " + current_version) + __log.info("Current version detected: " + current_version) info = Connection() new_version = info.getLatestVersionCode() from packaging import version if version.parse(current_version) >= version.parse(new_version): - __log.d("The version installed is the same or greater than the available one. " - "Current version: " + current_version + " | Available version: " + new_version) + __log.debug("The version installed is the same or greater than the available one. " + "Current version: " + current_version + " | Available version: " + new_version) print(Colors.FAIL + "You already have the latest version" + Colors.ENDC) exit(1) else: - __log.d("There is a new version available - new kernel upgrade process started") + __log.debug("There is a new version available - new kernel upgrade process started") print(Colors.OKGREEN + "There is a new version available." + Colors.ENDC) print(Colors.OKBLUE + "Downloading new version... " + Colors.ENDC + "| New version: " + new_version) - __log.d("Starting new version download... | New version: " + new_version) + __log.debug("Starting new version download... | New version: " + new_version) version_url = info.getLatestVersionURL() - __log.i("Downloading from: " + version_url) + __log.info("Downloading from: " + version_url) downloader = Downloader(version_url, new_version) download_path, current_date = downloader.startDownload() - __log.i("Downloaded to path: \"" + download_path + "\"") - __log.d("Starting dependencies installation...") + __log.info("Downloaded to path: \"" + download_path + "\"") + __log.debug("Starting dependencies installation...") print(Colors.OKBLUE + "Installing required dependencies... " + Colors.ENDC) Dependencies.installRequiredDependencies() - __log.d("Required dependencies installed/satisfied") - __log.d("Starting kernel decompression") + __log.debug("Required dependencies installed/satisfied") + __log.debug("Starting kernel decompression") animator.animate(Colors.OKBLUE + "Decompressing downloaded kernel..." + Colors.ENDC, Colors.OKBLUE) unzipper = UnZipper(download_path) kernel_folder = unzipper.unzip() animator.stop() - __log.d("Finished kernel decompression") + __log.debug("Finished kernel decompression") time.sleep(1) - __log.d("Starting kernel compilation...") + __log.debug("Starting kernel compilation...") print(Colors.OKBLUE + "Copying old configuration..." + Colors.ENDC) compiler = Compiler(kernel_folder, new_version, current_date) - __log.d("Copying old kernel boot config") + __log.debug("Copying old kernel boot config") if compiler.copy_latest_config(): - __log.d("Copied old kernel boot configuration") - __log.d("Adapting latest config for the new kernel version") + __log.debug("Copied old kernel boot configuration") + __log.debug("Adapting latest config for the new kernel version") animator.animate(Colors.OKBLUE + "Adapting old configuration to the new kernel..." + Colors.ENDC, Colors.OKBLUE) compiler.adaptOldConfig() animator.stop() - __log.d("Adapted old kernel configuration to the newer version") + __log.debug("Adapted old kernel configuration to the newer version") time.sleep(1) - __log.d("Performing kernel compilation...") + __log.debug("Performing kernel compilation...") print(Colors.OKBLUE + "Starting kernel compilation..." + Colors.ENDC) print(Colors.WARNING + "This process will take a long time to finish. You can do it " "in background by pressing \"Ctrl + Z\" and then, type \"bg\" at" @@ -119,42 +144,38 @@ def application(arg): Colors.BOLD) compiler.compileKernel() animator.stop() - __log.d("Kernel compilation finished") + __log.debug("Kernel compilation finished") time.sleep(1) - __log.d("Starting kernel installation...") + __log.debug("Starting kernel installation...") animator.animate(Colors.OKBLUE + "Installing the new kernel..." + Colors.ENDC, Colors.OKBLUE) compiler.installKernel() animator.stop() - __log.d("Finished correctly kernel installation. New version installed: " + new_version) + __log.debug("Finished correctly kernel installation. New version installed: " + new_version) time.sleep(1) print(Colors.OKGREEN + "Kernel completely installed. Now you should reboot in order to " "apply changes. New version: " + new_version + Colors.ENDC) - __log.d("Cleaning-up space for downloaded & compiled files") + __log.debug("Cleaning-up space for downloaded & compiled files") animator.animate(Colors.UNDERLINE + "Cleaning up used space..." + Colors.ENDC, None) cleanupSpace() animator.stop() - __log.d("Space cleaned-up") + __log.debug("Space cleaned-up") time.sleep(1) - __log.finish() exit(0) else: - __log.e("Impossible to copy latest kernel configuration. Aborting...") - __log.finish() + __log.error("Impossible to copy latest kernel configuration. Aborting...") except ImportError as e: raiserModuleNotFound(e) except KeyboardInterrupt: animator.force_stop() print("\n") print(Colors.FAIL + "User pressed Ctrl + C - stopping..." + Colors.ENDC) - __log.e("User pressed keyboard interrupt. Stopping program...") - __log.finish() + __log.error("User pressed keyboard interrupt. Stopping program...") exit(2) except Exception as e: print(e) animator.force_stop() - __log.e("Exception catch | " + str(e)) - __log.finish() + __log.error("Exception catch | " + str(e)) exit(3) @@ -166,6 +187,14 @@ def main(): "--usage", action="store_true", help="Show full usage of this program") + arguments.add_argument("-v", + "--version", + action="store_true", + help="Show program version") + arguments.add_argument("-c", + "--check", + action="store_true", + help="Only checks if there is any new version available") args = arguments.parse_args() application(args) diff --git a/kernel_upgrader/data_manager/__init__.py b/kernel_upgrader/data_manager/__init__.py index 1c00093..b836766 100644 --- a/kernel_upgrader/data_manager/__init__.py +++ b/kernel_upgrader/data_manager/__init__.py @@ -1,5 +1,6 @@ import os import subprocess +import logging from kernel_upgrader.exceptions import ( ExtractionError, @@ -10,6 +11,7 @@ InstallationError ) from kernel_upgrader.utils import * +from kernel_upgrader.values.Constants import LOG_KERNEL, LOG_COMPILER class UnZipper: @@ -19,7 +21,7 @@ def __init__(self, filename): self.__dir = os.path.dirname(filename) file_tar, file_tar_ext = os.path.splitext(filename) self.__file_unzip, file_unzip_ext = os.path.splitext(file_tar) - self.__log = Log.instance() + self.__log = logging.getLogger(LOG_KERNEL) def unzip(self): # type: () -> str @@ -33,7 +35,7 @@ def unzip(self): if os.path.exists(self.__file_unzip) and os.path.isdir(self.__file_unzip): return path.basename(path.normpath(self.__file_unzip)) else: - self.__log.e("There was an error while decompressing 'tar' file located at: " + self.__filename) + self.__log.error("There was an error while decompressing 'tar' file located at: " + self.__filename) raise ExtractionError( OutputColors.FAIL + "There was a problem while decompressing 'tar' file (file does not " "exists or is not a dir)" + OutputColors.ENDC) @@ -50,11 +52,12 @@ def __init__(self, kernel_folder, new_kernel_version, current_date): self.__decompressed_path = "{}/linux_{}_{}/".format(home_dir, new_kernel_version, current_date) - self.__log = Log.instance() - self.__log.d("Kernel path: \"" + self.__kernel_path + "\"") - self.__log.d("Decompressed kernel path: \"" + self.__decompressed_path + "\"") - self.__log.d("Removing old kernels in order to have enough space available on /root. We will only keep actually" - " installed version and the new one") + self.__log = logging.getLogger(LOG_KERNEL) + self.__log.debug("Kernel path: \"" + self.__kernel_path + "\"") + self.__log.debug("Decompressed kernel path: \"" + self.__decompressed_path + "\"") + self.__log.debug( + "Removing old kernels in order to have enough space available on /root. We will only keep actually" + " installed version and the new one") removeOldKernels() def copy_latest_config(self): @@ -68,100 +71,100 @@ def copy_latest_config(self): for entry in configs: if fnmatch(entry, pattern): files_found.append(entry) - self.__log.d("Files found: " + str(files_found)) + self.__log.debug("Files found: " + str(files_found)) any_found = next((config for config in files_found if kernel_version.rstrip() in config), None) if any_found is not None: - from kernel_upgrader.values.Constants import COPY_BOOT_CONFIG + from kernel_upgrader.values.Constants import COMPILE_COPY_BOOT_CONFIG - self.__log.d("Found old boot config - copying to: \"" + self.__kernel_path + "\"") - command = COPY_BOOT_CONFIG.format(kernel_version, self.__kernel_path) + self.__log.debug("Found old boot config - copying to: \"" + self.__kernel_path + "\"") + command = COMPILE_COPY_BOOT_CONFIG.format(kernel_version, self.__kernel_path) terminal_process = subprocess.run(command.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE) if terminal_process.returncode != 0: - self.__log.e("An error occurred while copying latest kernel. Error output: " + terminal_process.stderr - .decode("utf-8")) + self.__log.error( + "An error occurred while copying latest kernel. Error output: " + terminal_process.stderr + .decode("utf-8")) # self.__log.finish() raise CopyConfigError(OutputColors.FAIL + "No configuration was found or an error occurred while " "copying latest kernel boot configuration. Error output: " + terminal_process.stderr.decode("utf-8") + OutputColors.ENDC) else: - self.__log.d("Correctly copied old boot config | STDOUT log: " - + terminal_process.stdout.decode("utf-8")) + self.__log.debug("Correctly copied old boot config | STDOUT log: " + + terminal_process.stdout.decode("utf-8")) return True else: - self.__log.e("No boot configuration found for the current kernel version") + self.__log.error("No boot configuration found for the current kernel version") # self.__log.finish() raise CopyConfigError(OutputColors.FAIL + "No boot configuration was found for the current kernel version." " Searching a config for version \"" + kernel_version.rstrip() + "\" for these files in \"/boot/\" partition\n" + str(files_found) + OutputColors.ENDC) def adaptOldConfig(self): - from kernel_upgrader.values.Constants import ADAPT_OLD_CONFIG + from kernel_upgrader.values.Constants import COMPILE_ADAPT_OLD_CONFIG returnToHomeDir() - self.__log.d("Adapting old config copied in folder \"" + self.__kernel_path + "\"") - terminal_process = subprocess.run(ADAPT_OLD_CONFIG.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE, + self.__log.debug("Adapting old config copied in folder \"" + self.__kernel_path + "\"") + terminal_process = subprocess.run(COMPILE_ADAPT_OLD_CONFIG.split(), stderr=subprocess.PIPE, + stdout=subprocess.PIPE, cwd=self.__kernel_path) if terminal_process.returncode != 0: - self.__log.e("It was impossible to update the old config. Error output: " + terminal_process.stderr - .decode("utf-8")) + self.__log.error("It was impossible to update the old config. Error output: " + terminal_process.stderr + .decode("utf-8")) raise OldConfigAdaptationError(OutputColors.FAIL + "There was a problem while trying to update the old " "configuration for the new kernel. Please, go to kernel " "dir and run \"make menuconfig\" for" " updating manually. Error output: " + terminal_process.stderr.decode("utf'8") + OutputColors.ENDC) else: - self.__log.d("Correctly adapted old kernel configuration | STDOUT log: " - + terminal_process.stdout.decode("utf-8")) + self.__log.debug("Correctly adapted old kernel configuration | STDOUT log: " + + terminal_process.stdout.decode("utf-8")) def compileKernel(self): - from kernel_upgrader.values.Constants import COMPILE_NEW_KERNEL, REPO_URL + from kernel_upgrader.values.Constants import COMPILE_COMPILE_NEW_KERNEL, OP_REPO_URL returnToHomeDir() - self.__log.d("Starting kernel compilation - log available on \"kernel_upgrader.compiler.log\"") + self.__log.debug("Starting kernel compilation - log available on \"kernel_upgrader.compiler.log\"") number_of_cores = getCPUCount() if isDEBSystem(): - command = COMPILE_NEW_KERNEL.format(number_of_cores) + command = COMPILE_COMPILE_NEW_KERNEL.format(number_of_cores) process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.__kernel_path) - compiler_log = CompilerLog() - compiler_log.add("Compiling kernel with " + str(number_of_cores) + " cores") - compiler_log.add("Compiling kernel available in folder: \"" + self.__kernel_path + "\"") + compiler_log = logging.getLogger(LOG_COMPILER) + compiler_log.debug("Compiling kernel with " + str(number_of_cores) + " cores") + compiler_log.debug("Compiling kernel available in folder: \"" + self.__kernel_path + "\"") return_code = process.poll() while return_code is None: current_output = process.stdout.readline() if current_output: - compiler_log.add(current_output.strip().decode("utf-8")) + compiler_log.debug(current_output.strip().decode("utf-8")) return_code = process.poll() if return_code != 0: err = process.stderr.read().decode("utf-8") - compiler_log.finish() - self.__log.e("There was an error while compiling the new kernel. Error output: " + err) + self.__log.error("There was an error while compiling the new kernel. Error output: " + err) raise CompilationError(OutputColors.FAIL + "There was an error while compiling the new kernel. " "Error output: " + err + OutputColors.ENDC) else: - compiler_log.add("Correctly compiled kernel") - compiler_log.finish() - self.__log.d("Correctly compiled log") + compiler_log.debug("Correctly compiled kernel") + self.__log.debug("Correctly compiled log") else: - self.__log.e("RPM systems are not supported by this tool") + self.__log.error("RPM systems are not supported by this tool") raise RPMNotSupported(OutputColors.FAIL + "RPM systems are not supported by this tool right now: it works" " only on DEB ones.\nMaybe doing an upgrade of this program solve" " this problem (if RPM kernel upgrade is included in the new" - " upgrade. Check it on: \"" + REPO_URL + "\")" + " upgrade. Check it on: \"" + OP_REPO_URL + "\")" + OutputColors.ENDC) def installKernel(self): - from kernel_upgrader.values.Constants import INSTALL_NEW_KERNEL + from kernel_upgrader.values.Constants import COMPILE_INSTALL_NEW_KERNEL returnToHomeDir() - self.__log.d("Starting kernel installation | Kernel source installation path: " + self.__decompressed_path) - process = subprocess.run(INSTALL_NEW_KERNEL.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE, + self.__log.debug("Starting kernel installation | Kernel source installation path: " + self.__decompressed_path) + process = subprocess.run(COMPILE_INSTALL_NEW_KERNEL.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.__decompressed_path) if process.returncode != 0: - self.__log.e("There was an error while installing kernel. Error: " + process.stderr.decode("utf-8")) + self.__log.error("There was an error while installing kernel. Error: " + process.stderr.decode("utf-8")) raise InstallationError(OutputColors.FAIL + "There was an error while installing the new kernel module." " Do not reboot your computer as errors can happen and make " "your PC unbootable. Error output: " + process.stderr.decode("utf-8") + OutputColors.ENDC) else: - self.__log.d("Installed new kernel") + self.__log.debug("Installed new kernel") diff --git a/kernel_upgrader/net/DependenciesInstaller.py b/kernel_upgrader/net/DependenciesInstaller.py index f4d5f6d..03c4ea8 100644 --- a/kernel_upgrader/net/DependenciesInstaller.py +++ b/kernel_upgrader/net/DependenciesInstaller.py @@ -2,19 +2,18 @@ class Dependencies: @staticmethod def installRequiredDependencies(): import subprocess - from kernel_upgrader.values.Constants import DEPENDENCIES + import logging + from kernel_upgrader.values.Constants import C_DEPENDENCIES, LOG_KERNEL from kernel_upgrader.exceptions import UnableToInstallDependencies - from kernel_upgrader.utils import Log from kernel_upgrader.utils.colors import OutputColors as Colors - __log = Log.instance() - process = subprocess.run(DEPENDENCIES.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + __log = logging.getLogger(LOG_KERNEL) + process = subprocess.run(C_DEPENDENCIES.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) if process.returncode != 0: - __log.e("Impossible to install dependencies. Error output: " + process.stderr.decode("utf-8")) - # __log.finish() + __log.error("Impossible to install dependencies. Error output: " + process.stderr.decode("utf-8")) raise UnableToInstallDependencies(Colors.FAIL + "There was a problem while trying to install required " "dependencies. Please, install them manually: " - + DEPENDENCIES + "\nError output: " + process.stderr.decode("utf-8") + + + C_DEPENDENCIES + "\nError output: " + process.stderr.decode("utf-8") + Colors.ENDC) else: - __log.i("Dependencies installation finished") + __log.info("Dependencies installation finished") diff --git a/kernel_upgrader/net/Downloader.py b/kernel_upgrader/net/Downloader.py index 6cc4024..87ba545 100644 --- a/kernel_upgrader/net/Downloader.py +++ b/kernel_upgrader/net/Downloader.py @@ -1,11 +1,12 @@ +import logging + from kernel_upgrader.exceptions import raiserModuleNotFound, raiserContentNotAvailable -from kernel_upgrader.values.Constants import DOWNLOAD_LENGTH -from kernel_upgrader.utils import Log +from kernel_upgrader.values.Constants import WD_DOWNLOAD_LENGTH, LOG_KERNEL class Downloader: def __init__(self, url, version): - self.__log = Log.instance() + self.__log = logging.getLogger(LOG_KERNEL) try: from kernel_upgrader.utils import getHomeDir import datetime @@ -14,8 +15,7 @@ def __init__(self, url, version): self.__HOME = getHomeDir() self.__date = datetime.date.today().strftime("%d%m%y") except ImportError as e: - self.__log.e("Module needed not found -> " + str(e)) - # self.__log.finish() + self.__log.error("Module needed not found -> " + str(e)) raiserModuleNotFound(e) def startDownload(self): @@ -32,13 +32,13 @@ def startDownload(self): if not os.path.exists(partial_path): os.makedirs(partial_path) download_path = partial_path + filename - self.__log.d("Downloading to: " + download_path) + self.__log.debug("Downloading to: " + download_path) with open(download_path, "wb") as download: response = requests.get(self.__url, stream=True) - total_length = response.headers.get(DOWNLOAD_LENGTH) + total_length = response.headers.get(WD_DOWNLOAD_LENGTH) if total_length is None: download.close() - self.__log.e("The kernel is not available actually for download") + self.__log.error("The kernel is not available actually for download") raiserContentNotAvailable(response.content) else: for chunk in progress.bar(response.iter_content(chunk_size=1024), @@ -48,7 +48,8 @@ def startDownload(self): download.flush() download.close() length_in_mb = int(total_length) / 1000000 - self.__log.i("Downloaded " + str(total_length) + " bytes (" + str("%.2f" % length_in_mb) + " MB)") + self.__log.info( + "Downloaded " + str(total_length) + " bytes (" + str("%.2f" % length_in_mb) + " MB)") return download_path, self.__date except ImportError as e: raiserModuleNotFound(e) diff --git a/kernel_upgrader/net/PageInfo.py b/kernel_upgrader/net/PageInfo.py index 5dcd521..10b0ecb 100644 --- a/kernel_upgrader/net/PageInfo.py +++ b/kernel_upgrader/net/PageInfo.py @@ -1,6 +1,13 @@ -from kernel_upgrader.values.Constants import KERNEL_PAGE, PARSER, ASSIDE_ID, TABLE_ID, LATEST_LINK_ID +import logging + +from kernel_upgrader.values.Constants import ( + WI_KERNEL_PAGE, + WI_PARSER, + WI_ASSIDE_ID, + WI_TABLE_ID, + WI_LATEST_LINK_ID, + LOG_KERNEL) from kernel_upgrader.exceptions import raiserModuleNotFound -from kernel_upgrader.utils import Log class Connection: @@ -9,23 +16,22 @@ def __init__(self): from bs4 import BeautifulSoup import lxml import requests - saved_page_content = requests.get(KERNEL_PAGE).content - self.__soupObject = BeautifulSoup(saved_page_content, PARSER) + saved_page_content = requests.get(WI_KERNEL_PAGE).content + self.__soupObject = BeautifulSoup(saved_page_content, WI_PARSER) except ImportError as e: - Log.instance().e("Modules not found. " + str(e)) - Log.instance().finish() + logging.getLogger(LOG_KERNEL).error("Modules not found. " + str(e)) raiserModuleNotFound(e) def getLatestVersionCode(self): - aside = self.__soupObject.find(id=ASSIDE_ID) - table = aside.find(id=TABLE_ID) - td = table.find(id=LATEST_LINK_ID) + aside = self.__soupObject.find(id=WI_ASSIDE_ID) + table = aside.find(id=WI_TABLE_ID) + td = table.find(id=WI_LATEST_LINK_ID) html_latest_version = td.a return html_latest_version.get_text() def getLatestVersionURL(self): - aside = self.__soupObject.find(id=ASSIDE_ID) - table = aside.find(id=TABLE_ID) - td = table.find(id=LATEST_LINK_ID) + aside = self.__soupObject.find(id=WI_ASSIDE_ID) + table = aside.find(id=WI_TABLE_ID) + td = table.find(id=WI_LATEST_LINK_ID) html_latest_link = td.a return html_latest_link.get('href') diff --git a/kernel_upgrader/utils/Singleton.py b/kernel_upgrader/utils/Singleton.py deleted file mode 100644 index 4ae81da..0000000 --- a/kernel_upgrader/utils/Singleton.py +++ /dev/null @@ -1,37 +0,0 @@ -class Singleton: - """ - A non-thread-safe helper class to ease implementing singletons. - This should be used as a decorator -- not a metaclass -- to the - class that should be a singleton. - - The decorated class can define one `__init__` function that - takes only the `self` argument. Also, the decorated class cannot be - inherited from. Other than that, there are no restrictions that apply - to the decorated class. - - To get the singleton instance, use the `instance` method. Trying - to use `__call__` will result in a `TypeError` being raised. - - """ - - def __init__(self, decorated): - self._decorated = decorated - - def instance(self): - """ - Returns the singleton instance. Upon its first call, it creates a - new instance of the decorated class and calls its `__init__` method. - On all subsequent calls, the already created instance is returned. - - """ - try: - return self._instance - except AttributeError: - self._instance = self._decorated() - return self._instance - - def __call__(self): - raise TypeError('Singletons must be accessed through `instance()`.') - - def __instancecheck__(self, inst): - return isinstance(inst, self._decorated) diff --git a/kernel_upgrader/utils/__init__.py b/kernel_upgrader/utils/__init__.py index 9e6daf9..443b67d 100644 --- a/kernel_upgrader/utils/__init__.py +++ b/kernel_upgrader/utils/__init__.py @@ -1,10 +1,8 @@ from datetime import datetime from threading import Thread -from kernel_upgrader.utils.Singleton import Singleton from kernel_upgrader.utils.colors import * from kernel_upgrader.utils.anim import * -from kernel_upgrader.utils.Singleton import * def getHomeDir(): @@ -15,9 +13,9 @@ def getHomeDir(): def getLinuxVersion(): # type: () -> str import subprocess - from kernel_upgrader.values.Constants import UNAME + from kernel_upgrader.values.Constants import C_UNAME - command_execution = subprocess.run(UNAME.split(), stdout=subprocess.PIPE) + command_execution = subprocess.run(C_UNAME.split(), stdout=subprocess.PIPE) return command_execution.stdout.decode("utf-8") @@ -35,10 +33,10 @@ def returnToHomeDir(): def isDEBSystem(): # type: () -> bool import subprocess - from kernel_upgrader.values.Constants import RPM_OR_DEB + from kernel_upgrader.values.Constants import COMPILE_RPM_OR_DEB try: - process = subprocess.Popen(RPM_OR_DEB.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process = subprocess.Popen(COMPILE_RPM_OR_DEB.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.communicate() return_code = process.returncode if return_code != 0: @@ -51,22 +49,23 @@ def isDEBSystem(): def removeOldKernels(): import subprocess - from kernel_upgrader.values.Constants import CLEAN_KERNELS + from kernel_upgrader.values.Constants import C_CLEAN_KERNELS - subprocess.run(CLEAN_KERNELS.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE) + subprocess.run(C_CLEAN_KERNELS.split(), stderr=subprocess.PIPE, stdout=subprocess.PIPE) def cleanupOldLogs(): - from kernel_upgrader.values.Constants import FILE_PATH, FILENAME, COMPILER_FILENAME, TARFILE_FILENAME,\ - TARFILE_COMPILER_FILENAME + from kernel_upgrader.values.Constants import LOG_FILE_PATH, LOG_FILENAME, LOG_COMPILER_FILENAME, \ + LOG_TARFILE_FILENAME, \ + LOG_TARFILE_COMPILER_FILENAME import tarfile import os - kernel_log_filename = FILE_PATH + FILENAME - compiler_log_filename = FILE_PATH + COMPILER_FILENAME + kernel_log_filename = LOG_FILE_PATH + LOG_FILENAME + compiler_log_filename = LOG_FILE_PATH + LOG_COMPILER_FILENAME - tar_log_filename = FILE_PATH + TARFILE_FILENAME - tar_compiler_log_filename = FILE_PATH + TARFILE_COMPILER_FILENAME + tar_log_filename = LOG_FILE_PATH + LOG_TARFILE_FILENAME + tar_compiler_log_filename = LOG_FILE_PATH + LOG_TARFILE_COMPILER_FILENAME if os.path.exists(kernel_log_filename): if os.path.exists(tar_log_filename): @@ -124,16 +123,17 @@ def isRunningInBackground(): def cleanupSpace(): import subprocess - from kernel_upgrader.values.Constants import CLEAN_DOWNLOADS + import logging + from kernel_upgrader.values.Constants import C_CLEAN_DOWNLOADS, LOG_KERNEL from kernel_upgrader.utils.colors import OutputColors as Colors - command = CLEAN_DOWNLOADS.format(getHomeDir() + "/*") + command = C_CLEAN_DOWNLOADS.format(getHomeDir() + "/*") clean_process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) clean_process.communicate() return_code = clean_process.returncode if return_code != 0: - log = Log.instance() - log.e("There was an error while trying to clean data in \"" + getHomeDir() + "\"") + log = logging.getLogger(LOG_KERNEL) + log.error("There was an error while trying to clean data in \"" + getHomeDir() + "\"") raise RuntimeError(Colors.FAIL + "We were not able to clean data in \"" + getHomeDir() + "\". Please, clean it" " up manually" + Colors.ENDC) @@ -141,10 +141,10 @@ def cleanupSpace(): def exportVersion(): import pickle - from kernel_upgrader.values.Constants import VERSION + from kernel_upgrader.values.Constants import OP_VERSION filename = "version.json" - version_dict = {"version": VERSION} + version_dict = {"version": OP_VERSION} with open(filename, "wb") as file: pickle.dump(version_dict, file, pickle.HIGHEST_PROTOCOL) @@ -153,74 +153,8 @@ def isNewVersionAvailable(): # type: () -> bool import requests import pickle - from kernel_upgrader.values.Constants import VERSION, VERSION_RAW + from kernel_upgrader.values.Constants import OP_VERSION, OP_VERSION_RAW - response = requests.get(VERSION_RAW) + response = requests.get(OP_VERSION_RAW) version_dict = pickle.loads(response.content) - return version_dict["version"] != VERSION - - -@Singleton -class Log: - def __init__(self): - import os - from kernel_upgrader.values.Constants import FILE_PATH, FILENAME - cleanupOldLogs() - if not os.path.exists(FILE_PATH): - os.makedirs(FILE_PATH) - self.__fileLog = open(FILE_PATH + FILENAME, "w") - self.__threads = [] - - def d(self, message=None): - thread = Thread(target=self.__write, args=("DEBUG", message,)) - self.__threads.append(thread) - thread.start() - - def i(self, message=None): - thread = Thread(target=self.__write, args=("INFO", message,)) - self.__threads.append(thread) - thread.start() - - def e(self, message=None): - thread = Thread(target=self.__write, args=("ERROR", message,)) - self.__threads.append(thread) - thread.start() - - def w(self, message=None): - thread = Thread(target=self.__write, args=("WARNING", message,)) - self.__threads.append(thread) - thread.start() - - def __write(self, typo=None, message=None): - log_date = datetime.now().strftime("%H:%M:%S@%d/%m/%Y [" + typo + "]: ") - self.__fileLog.write(log_date + message + "\n") - self.__fileLog.flush() - - def finish(self): - for saved_thread in self.__threads: - if saved_thread.isAlive(): - saved_thread.join(1.0) - self.__fileLog.close() - - -class CompilerLog: - def __init__(self): - from kernel_upgrader.values.Constants import FILE_PATH, COMPILER_FILENAME - self.__fileLog = open(FILE_PATH + COMPILER_FILENAME, "w") - self.__threads = [] - - def add(self, message): - thread = Thread(target=self.__write, args=(message,)) - self.__threads.append(thread) - thread.start() - - def __write(self, message): - log_date = datetime.now().strftime("%H:%M:%S@%d/%m/%Y [COMPILER]: ") - self.__fileLog.write(log_date + message + "\n") - self.__fileLog.flush() - - def finish(self): - for saved_thread in self.__threads: - if saved_thread.isAlive(): - saved_thread.join(1.0) - self.__fileLog.close() + return version_dict["version"] != OP_VERSION diff --git a/kernel_upgrader/utils/logger.py b/kernel_upgrader/utils/logger.py new file mode 100644 index 0000000..d2df2d0 --- /dev/null +++ b/kernel_upgrader/utils/logger.py @@ -0,0 +1,17 @@ +import logging + +from kernel_upgrader.values.Constants import LOG_FORMAT_TYPE + + +def setup_logging(logger_name: str, log_file: str, level=logging.DEBUG): + new_logging = logging.getLogger(logger_name) + logging_formatter = logging.Formatter(LOG_FORMAT_TYPE) + logging_file_handler = logging.FileHandler(log_file, mode="w") + logging_stream_handler = logging.StreamHandler() + + logging_file_handler.setFormatter(logging_formatter) + logging_stream_handler.setFormatter(logging_formatter) + + new_logging.setLevel(level) + new_logging.addHandler(logging_file_handler) + new_logging.addHandler(logging_stream_handler) diff --git a/kernel_upgrader/values/Constants.py b/kernel_upgrader/values/Constants.py index 8c9df56..1f905be 100644 --- a/kernel_upgrader/values/Constants.py +++ b/kernel_upgrader/values/Constants.py @@ -1,54 +1,57 @@ from kernel_upgrader.utils.colors import OutputColors as Colors # Kernel download parameters -KERNEL_PAGE = "https://www.kernel.org/" -PARSER = "lxml" -ASSIDE_ID = "featured" -TABLE_ID = "latest" -LATEST_LINK_ID = "latest_link" +WI_KERNEL_PAGE = "https://www.kernel.org/" +WI_PARSER = "lxml" +WI_ASSIDE_ID = "featured" +WI_TABLE_ID = "latest" +WI_LATEST_LINK_ID = "latest_link" # Download parameters -DOWNLOAD_LENGTH = "content-length" +WD_DOWNLOAD_LENGTH = "content-length" # Other commands -UNAME = "uname -r" -DEPENDENCIES = "apt-get install -y build-essential libncurses5-dev gcc libssl-dev bc flex bison libelf-dev" -CLEAN_KERNELS = "dpkg -l 'linux-*' | sed '/^ii/!d;/'\"$(uname -r " \ - "| sed \"s/\(.*\)-\([^0-9]\+\)/\1/\")\"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' " \ - "| xargs apt-get -y purge" -CLEAN_DOWNLOADS = "rm -r {}" +C_UNAME = "uname -r" +C_DEPENDENCIES = "apt-get install -y build-essential libncurses5-dev gcc libssl-dev bc flex bison libelf-dev" +C_CLEAN_KERNELS = "dpkg -l 'linux-*' | sed '/^ii/!d;/'\"$(uname -r " \ + "| sed \"s/\(.*\)-\([^0-9]\+\)/\1/\")\"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' " \ + "| xargs apt-get -y purge" +C_CLEAN_DOWNLOADS = "rm -r {}" # Log params -FILE_PATH = "/var/log/" -FILENAME = "kernel_upgrader.log" -COMPILER_FILENAME = "kernel_upgrader.compiler.log" -TARFILE_FILENAME = "kernel_upgrader.latest.tar.gz" -TARFILE_COMPILER_FILENAME = "kernel_upgrader.compiler.tar.gz" +LOG_KERNEL = "kernel_logging" +LOG_COMPILER = "compiler_logging" +LOG_FILE_PATH = "/var/log/" +LOG_FILENAME = "kernel_upgrader.log" +LOG_COMPILER_FILENAME = "kernel_upgrader.compiler.log" +LOG_TARFILE_FILENAME = "kernel_upgrader.latest.tar.gz" +LOG_TARFILE_COMPILER_FILENAME = "kernel_upgrader.compiler.tar.gz" +LOG_FORMAT_TYPE = "%(asctime)s | [%(levelname)s]: %(message)s" # Compilation commands -COPY_BOOT_CONFIG = "cp -v /boot/config-{} {}/.config" -ADAPT_OLD_CONFIG = "make olddefconfig" -RPM_OR_DEB = "/usr/bin/rpm -q -f /usr/bin/dpkg" -COMPILE_NEW_KERNEL = "make -j{} deb-pkg" -INSTALL_NEW_KERNEL = "dpkg -i linux-*.deb" +COMPILE_COPY_BOOT_CONFIG = "cp -v /boot/config-{} {}/.config" +COMPILE_ADAPT_OLD_CONFIG = "make olddefconfig" +COMPILE_RPM_OR_DEB = "/usr/bin/rpm -q -f /usr/bin/dpkg" +COMPILE_COMPILE_NEW_KERNEL = "make -j{} deb-pkg" +COMPILE_INSTALL_NEW_KERNEL = "dpkg -i linux-*.deb" # Other params -REPO_URL = "https://goo.gl/ZJ4zP9" -VERSION = "1.17.2" -VERSION_RAW = "https://github.com/Javinator9889/KernelUpgrader/raw/master/version.json" +OP_REPO_URL = "https://goo.gl/ZJ4zP9" +OP_VERSION = "1.18" +OP_VERSION_RAW = "https://github.com/Javinator9889/KernelUpgrader/raw/master/version.json" # Program extended usage -__program_name = """Kernel Upgrader for Linux""" -USAGE = Colors.HEADER + __program_name + Colors.ENDC + "\nUse this tool for upgrading your Linux kernel " + \ - Colors.UNDERLINE + "automatically" + Colors.ENDC + " with no user interaction. For this purpose," + \ - " the tool needs " + Colors.OKGREEN + "admin rights" + Colors.ENDC + " in order to install required" + \ - " dependencies and the kernel when everything has finished.\nYou can find " + Colors.BOLD + "the" + \ - " program logs" + Colors.ENDC + " at the following location: " + Colors.OKBLUE + \ - "\n\t - " + FILE_PATH + FILENAME + Colors.ENDC + ": all program logs\n\t - " + Colors.OKBLUE + \ - FILE_PATH + COMPILER_FILENAME + Colors.ENDC + \ - ": kernel compiler logs\n\nYou can find more information about this program at the following URL: " + \ - Colors.UNDERLINE + REPO_URL + Colors.ENDC + "\nModules that you will need to install: \n" + Colors.OKBLUE + \ - "\t- pip install beautifulsoup4\n\t- pip install lxml\n\t- pip install requests\n\t- pip install clint\n\t" \ - "- pip install psutil" + Colors.ENDC + Colors.BOLD + "\n\nIf you find any module required that is not " \ - "mentioned above, please submit it at the given URL" + \ - Colors.ENDC +EXU_PROGRAM_NAME = """Kernel Upgrader for Linux""" +EXU_USAGE = Colors.HEADER + EXU_PROGRAM_NAME + Colors.ENDC + "\nUse this tool for upgrading your Linux kernel " + \ + Colors.UNDERLINE + "automatically" + Colors.ENDC + " with no user interaction. For this purpose," + \ + " the tool needs " + Colors.OKGREEN + "admin rights" + Colors.ENDC + " in order to install required" + \ + " dependencies and the kernel when everything has finished.\nYou can find " + Colors.BOLD + "the" + \ + " program logs" + Colors.ENDC + " at the following location: " + Colors.OKBLUE + \ + "\n\t - " + LOG_FILE_PATH + LOG_FILENAME + Colors.ENDC + ": all program logs\n\t - " + Colors.OKBLUE + \ + LOG_FILE_PATH + LOG_COMPILER_FILENAME + Colors.ENDC + \ + ": kernel compiler logs\n\nYou can find more information about this program at the following URL: " + \ + Colors.UNDERLINE + OP_REPO_URL + Colors.ENDC + "\nModules that you will need to install: \n" \ + + Colors.OKBLUE + "\t- pip install beautifulsoup4\n\t- pip install lxml\n\t- pip install requests" \ + "\n\t- pip install clint\n\t- pip install psutil" + Colors.ENDC + Colors.BOLD + \ + "\n\nIf you find any module required that is not mentioned above, please submit it at the given URL" + \ + Colors.ENDC diff --git a/setup.py b/setup.py index f2bcf46..2a9f0f4 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages from sys import version -from kernel_upgrader.values.Constants import VERSION +from kernel_upgrader.values.Constants import OP_VERSION if version < '3': raise RuntimeError("Python v3 at least needed") @@ -17,7 +17,7 @@ setup( name='KernelUpgrader', - version=VERSION, + version=OP_VERSION, packages=find_packages(), url='https://goo.gl/ZJ4zP9', license='GPL-3.0', diff --git a/version.json b/version.json index 2dcae024b73fc3aff932e63d9e56e3793ed30e97..00ad4abf44031d71f9366a0ed6744c5d20b5ac0a 100644 GIT binary patch literal 32 jcmZo*nJUTv0kuKR&0Db@o3foll* literal 34 lcmZo*nJUfz0kuKU5r8BHnH0|1im30(jH