-
Notifications
You must be signed in to change notification settings - Fork 3
/
__init__.py
177 lines (161 loc) · 9.76 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import os
import subprocess
import logging
from kernel_upgrader.exceptions import (
ExtractionError,
CopyConfigError,
OldConfigAdaptationError,
CompilationError,
RPMNotSupported,
InstallationError
)
from kernel_upgrader.utils import *
from kernel_upgrader.values.Constants import LOG_KERNEL, LOG_COMPILER
class UnZipper:
def __init__(self, filename):
returnToHomeDir()
self.__filename = 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 = logging.getLogger(LOG_KERNEL)
def unzip(self):
# type: () -> str
import tarfile
import os.path as path
returnToHomeDir()
opened_tar_file = tarfile.open(self.__filename, "r:*")
opened_tar_file.extractall(path=self.__dir)
opened_tar_file.close()
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.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)
class Compiler:
def __init__(self, kernel_folder, new_kernel_version, current_date):
returnToHomeDir()
home_dir = getHomeDir()
self.__kernel_path = "{}/linux_{}_{}/{}".format(home_dir,
new_kernel_version,
current_date,
kernel_folder)
self.__decompressed_path = "{}/linux_{}_{}/".format(home_dir,
new_kernel_version,
current_date)
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")
are_kernels_deleted, stdout, stderr = removeOldKernels()
if not are_kernels_deleted:
self.__log.warning("Old data was not deleted or does not exists - more info: " + stderr)
else:
self.__log.warning("Old data successfully removed - more info: " + stdout)
def copy_latest_config(self):
from fnmatch import fnmatch
returnToHomeDir()
kernel_version = getLinuxVersion()
configs = os.listdir("/boot/")
pattern = "config-*"
files_found = []
for entry in configs:
if fnmatch(entry, pattern):
files_found.append(entry)
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 COMPILE_COPY_BOOT_CONFIG
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.error(
"An error occurred while copying latest kernel. Error output: " + terminal_process.stderr
.decode("utf-8"))
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.debug("Correctly copied old boot config | STDOUT log: "
+ terminal_process.stdout.decode("utf-8"))
return True
else:
self.__log.error("No boot configuration found for the current kernel version")
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 COMPILE_ADAPT_OLD_CONFIG
returnToHomeDir()
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.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.debug("Correctly adapted old kernel configuration | STDOUT log: "
+ terminal_process.stdout.decode("utf-8"))
def compileKernel(self):
from kernel_upgrader.values.Constants import COMPILE_COMPILE_NEW_KERNEL, OP_REPO_URL
returnToHomeDir()
self.__log.debug("Starting kernel compilation - log available on \"kernel_upgrader.compiler.log\"")
number_of_cores = getCPUCount()
if isDEBSystem():
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 = 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.debug(current_output.strip().decode("utf-8"))
return_code = process.poll()
if return_code != 0:
err = process.stderr.read().decode("utf-8")
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.debug("Correctly compiled kernel")
self.__log.debug("Correctly compiled log")
else:
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: \"" + OP_REPO_URL + "\")"
+ OutputColors.ENDC)
def installKernel(self):
from glob import glob
from kernel_upgrader.values.Constants import COMPILE_INSTALL_NEW_KERNEL, COMPILE_DEB_PKG
returnToHomeDir()
self.__log.debug("Starting kernel installation | Kernel source installation path: " + self.__decompressed_path)
self.__log.info("Using \"glob\" for applying special chars to command")
deb_pkg_glob = glob(self.__decompressed_path + COMPILE_DEB_PKG)
process = subprocess.run(COMPILE_INSTALL_NEW_KERNEL.split() + deb_pkg_glob,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
cwd=self.__decompressed_path)
if process.returncode != 0:
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.debug("Installed new kernel")