diff --git a/README.md b/README.md
index a925ff4..69b6636 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ These kernels are considerably out of date and have shown to fail to install pro
## What happens if a kernel installation fails
The application will show a message that it has encountered an issue, and the log inside the progress window, should have the information required to understand why.
-In the event of a failure, the application will try to reinstall the kernel using the version previously installed.
+In the event of a failure, the application will attempt to reinstall the kernel using the version previously installed.
# Community based kernels
@@ -64,10 +64,6 @@ By default, the application will use `bootctl` to distinguish which bootloader (
`grub-mkconfig` is run to update the grub.cfg file.
-## systemd-boot
-
-`bootctl --no-variables ---graceful update` is run to update systemd-boot entries
-
# Advanced settings
## Bootloader settings
@@ -118,12 +114,16 @@ community = [
{ name = "linux-nitrous", description = "Modified Linux kernel optimized for Skylake and newer, compiled using clang", headers = "linux-nitrous-headers", repository = "chaotic-aur" },
]
+[logging]
+# Logging is either info or debug
+loglevel = "info"
+
# custom bootloader example
#[bootloader]
#name = "grub"
#grub_config = "/boot/grub/grub.cfg"
-
```
+
## Adding new community based kernels
Further Kernels can be added using the same format.
@@ -140,6 +140,11 @@ Using the Update switch inside Advanced Settings, will force the application to
This cache file may take a little while to generate since archived Arch kernel package data is being retrieved from the ALA.
+Once the cache file is in place, the application also queries the RESTful API using https://archlinux.org/packages/search/json to search for package updates.
+It extracts the `last_update` and compares it against the cache timestamp.
+
+That way the application will include the latest kernel versions.
+
# Logs
Logs can be found inside `/var/log/archlinux-kernel-manager`
diff --git a/usr/share/archlinux-kernel-manager/akm.css b/usr/share/archlinux-kernel-manager/akm.css
index 2f67a4b..6754ae9 100644
--- a/usr/share/archlinux-kernel-manager/akm.css
+++ b/usr/share/archlinux-kernel-manager/akm.css
@@ -75,6 +75,11 @@ label#label_active_kernel {
font-size: 12px;
}
+label#label_flowbox_message{
+ padding: 10px 10px 10px 10px;
+ font-size: medium;
+}
+
label#label_stack_kernel {
font-size: 20px;
font-weight: 600;
diff --git a/usr/share/archlinux-kernel-manager/defaults/config.toml b/usr/share/archlinux-kernel-manager/defaults/config.toml
index 3ea002f..419c4cf 100644
--- a/usr/share/archlinux-kernel-manager/defaults/config.toml
+++ b/usr/share/archlinux-kernel-manager/defaults/config.toml
@@ -25,6 +25,10 @@ community = [
{ name = "linux-nitrous", description = "Modified Linux kernel optimized for Skylake and newer, compiled using clang", headers = "linux-nitrous-headers", repository = "chaotic-aur" },
]
+[logging]
+# Logging is either info or debug
+loglevel = "info"
+
# Custom bootloader example
# Only systemd-boot or grub are valid names
# When using grub also set grub_config
diff --git a/usr/share/archlinux-kernel-manager/libs/Kernel.py b/usr/share/archlinux-kernel-manager/libs/Kernel.py
index 69a1bcd..c379dae 100644
--- a/usr/share/archlinux-kernel-manager/libs/Kernel.py
+++ b/usr/share/archlinux-kernel-manager/libs/Kernel.py
@@ -25,7 +25,7 @@ class Kernel:
.date()
)
- if datetime_value_other > datetime_value_self:
+ if datetime_value_other >= datetime_value_self:
return datetime_value_other
diff --git a/usr/share/archlinux-kernel-manager/libs/functions.py b/usr/share/archlinux-kernel-manager/libs/functions.py
index b8a8e87..772ff86 100644
--- a/usr/share/archlinux-kernel-manager/libs/functions.py
+++ b/usr/share/archlinux-kernel-manager/libs/functions.py
@@ -47,7 +47,6 @@ supported_kernels_dict = {}
community_kernels_dict = {}
pacman_repos_list = []
process_timeout = 200
-
sudo_username = os.getlogin()
home = "/home/" + str(sudo_username)
@@ -60,6 +59,9 @@ pacman_lockfile = "/var/lib/pacman/db.lck"
# pacman conf file
pacman_conf_file = "/etc/pacman.conf"
+# pacman cach dir
+pacman_cache = "/var/cache/pacman/pkg"
+
# thread names
thread_get_kernels = "thread_get_kernels"
thread_get_community_kernels = "thread_get_community_kernels"
@@ -83,15 +85,12 @@ config_file_default = "%s/defaults/config.toml" % base_dir
config_dir = "%s/.config/archlinux-kernel-manager" % home
config_file = "%s/.config/archlinux-kernel-manager/config.toml" % home
+
logger = logging.getLogger("logger")
# create console handler and set level to debug
ch = logging.StreamHandler()
-
-logger.setLevel(logging.DEBUG)
-ch.setLevel(logging.DEBUG)
-
# create formatter
formatter = logging.Formatter(
"%(asctime)s:%(levelname)s > %(message)s", "%Y-%m-%d %H:%M:%S"
@@ -190,26 +189,26 @@ def get_latest_kernel_updates(self):
response.json()["results"][0]["last_update"],
"%Y-%m-%dT%H:%M:%S.%f%z",
).date()
- ) > (
+ ) >= (
datetime.datetime.strptime(
cache_timestamp, "%Y-%m-%d %H-%M-%S"
).date()
):
- logger.info(
- "Linux kernel package updated, cache refresh required"
- )
+ logger.info("Linux kernel package updated")
refresh_cache(self)
return True
else:
- logger.info(
- "Linux kernel package not updated, cache refresh not required"
- )
+ logger.info("Linux kernel package not updated")
return False
+ else:
+ logger.error("Failed to get valid response to check kernel update")
+ logger.error(response.text)
+ return False
else:
logger.info("Kernel update check not required")
@@ -327,24 +326,48 @@ def update_config(config_data, bootloader):
def read_config(self):
try:
- logger.debug("Config file = %s" % config_file)
- logger.info("Reading in config file")
+ logger.info("Reading in config file %s" % config_file)
config_data = None
with open(config_file, "rb") as f:
config_data = tomlkit.load(f)
- for official_kernel in config_data["kernels"]["official"]:
- supported_kernels_dict[official_kernel["name"]] = (
- official_kernel["description"],
- official_kernel["headers"],
- )
+ if (
+ config_data.get("kernels")
+ and "official" in config_data["kernels"] is not None
+ ):
+ for official_kernel in config_data["kernels"]["official"]:
+ supported_kernels_dict[official_kernel["name"]] = (
+ official_kernel["description"],
+ official_kernel["headers"],
+ )
- for community_kernel in config_data["kernels"]["community"]:
- community_kernels_dict[community_kernel["name"]] = (
- community_kernel["description"],
- community_kernel["headers"],
- community_kernel["repository"],
- )
+ if (
+ config_data.get("kernels")
+ and "community" in config_data["kernels"] is not None
+ ):
+ for community_kernel in config_data["kernels"]["community"]:
+ community_kernels_dict[community_kernel["name"]] = (
+ community_kernel["description"],
+ community_kernel["headers"],
+ community_kernel["repository"],
+ )
+
+ if (
+ config_data.get("logging") is not None
+ and "loglevel" in config_data["logging"] is not None
+ ):
+
+ loglevel = config_data["logging"]["loglevel"].lower()
+ logger.info("Setting loglevel to %s" % loglevel)
+ if loglevel == "debug":
+ logger.setLevel(logging.DEBUG)
+ elif loglevel == "info":
+ logger.setLevel(logging.INFO)
+ else:
+ logger.warning("Invalid logging level set, use info / debug")
+ logger.setLevel(logging.INFO)
+ else:
+ logger.setLevel(logging.INFO)
return config_data
except Exception as e:
@@ -406,6 +429,16 @@ def write_cache():
# install from the ALA
def install_archive_kernel(self):
try:
+ # package cache
+ logger.debug("Cleaning pacman cache, removing official packages")
+ if os.path.exists(pacman_cache):
+ for root, dirs, files in os.walk(pacman_cache):
+ for name in files:
+ for official_kernel in supported_kernels_dict.keys():
+ if name.startswith(official_kernel):
+ if os.path.exists(os.path.join(root, name)):
+ os.remove(os.path.join(root, name))
+
install_cmd_str = [
"pacman",
"-U",
@@ -424,14 +457,14 @@ def install_archive_kernel(self):
" ".join(install_cmd_str),
)
- event_log = []
+ error = False
+
self.messages_queue.put(event)
with subprocess.Popen(
install_cmd_str,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- bufsize=1,
universal_newlines=True,
env=locale_env,
) as process:
@@ -439,96 +472,62 @@ def install_archive_kernel(self):
if process.poll() is not None:
break
for line in process.stdout:
- print(line.strip())
+ if logger.getEffectiveLevel() == 10:
+ print(line.strip())
self.messages_queue.put(line)
- event_log.append(line.lower().strip())
-
- time.sleep(0.3)
-
- error = None
-
- if (
- "installation finished. no error reported."
- or "initcpio image generation successful" in event_log
- ):
- error = False
-
- else:
- if error is None:
- # check errors and indicate to user install failed
- for log in event_log:
- # if "installation finished. no error reported." in log:
- # error = False
- # break
- if "error" in log or "errors" in log:
- event = (
- "%s [ERROR]: Errors have been encountered during installation\n"
- % (datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"))
- )
-
- logger.error(log)
-
- self.messages_queue.put(event)
-
- self.errors_found = True
-
+ if "no space left on device" in line.lower().strip():
+ self.restore_kernel = None
error = True
-
- GLib.idle_add(
- show_mw,
- self,
- "System changes",
- f"Kernel {self.action} failed\n"
- f"There have been errors, please review the logs\n",
- "images/48x48/akm-warning.png",
- priority=GLib.PRIORITY_DEFAULT,
- )
-
break
+ if "initcpio" in line.lower().strip():
+ if "image generation successful" in line.lower().strip():
+ error = False
+ break
+ if (
+ "installation finished. no error reported"
+ in line.lower().strip()
+ ):
+ error = False
+ break
+ if (
+ "error" in line.lower().strip()
+ or "errors" in line.lower().strip()
+ ):
+ error = True
+ break
+
+ # time.sleep(0.1)
+
+ if error is True:
+
+ self.errors_found = True
+
+ error = True
+
+ GLib.idle_add(
+ show_mw,
+ self,
+ "System changes",
+ f"Kernel {self.action} failed\n"
+ f"There have been errors, please review the logs",
+ priority=GLib.PRIORITY_DEFAULT,
+ )
# query to check if kernel installed
if check_kernel_installed(self.kernel.name + "-headers") and error is False:
-
- self.kernel_state_queue.put((0, "install", self.kernel.name + "-headers"))
-
- event = "%s [INFO]: Installation of %s-headers completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
-
- self.messages_queue.put(event)
-
+ self.kernel_state_queue.put((0, "install"))
else:
- self.kernel_state_queue.put((1, "install", self.kernel.name + "-headers"))
-
- event = "%s [ERROR]: Installation of %s-headers failed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
+ self.kernel_state_queue.put((1, "install"))
self.errors_found = True
self.messages_queue.put(event)
if check_kernel_installed(self.kernel.name) and error is False:
- self.kernel_state_queue.put((0, "install", self.kernel.name))
-
- event = "%s [INFO]: Installation of kernel %s completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
-
- self.messages_queue.put(event)
-
+ self.kernel_state_queue.put((0, "install"))
else:
- self.kernel_state_queue.put((1, "install", self.kernel.name))
-
- event = "%s [ERROR]: Installation of kernel %s failed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
-
- self.messages_queue.put(event)
+ self.kernel_state_queue.put((1, "install"))
+ self.errors_found = True
# signal to say end reached
self.kernel_state_queue.put(None)
@@ -536,15 +535,18 @@ def install_archive_kernel(self):
except Exception as e:
logger.error("Exception in install_archive_kernel(): %s" % e)
- GLib.idle_add(
- show_mw,
- self,
- "System changes",
- f"Kernel {self.action} failed\n"
- f"There have been errors, please review the logs\n",
- "images/48x48/akm-warning.png",
- priority=GLib.PRIORITY_DEFAULT,
- )
+ # GLib.idle_add(
+ # show_mw,
+ # self,
+ # "System changes",
+ # f"Kernel {self.action} failed\n"
+ # f"There have been errors, please review the logs\n",
+ # "images/48x48/akm-warning.png",
+ # priority=GLib.PRIORITY_DEFAULT,
+ # )
+ finally:
+ if os.path.exists(self.lockfile):
+ os.unlink(self.lockfile)
def refresh_cache(self):
@@ -712,6 +714,7 @@ def parse_archive_html(response, linux_kernel):
version is not None
and url is not None
and headers is not None
+ and file_format == ".pkg.tar.zst"
and datetime.datetime.now().year
- datetime.datetime.strptime(
last_modified, "%d-%b-%Y %H:%M"
@@ -911,10 +914,13 @@ def check_kernel_installed(name):
if process_kernel_query.returncode == 0:
for line in out.decode("utf-8").splitlines():
if line.split(" ")[0] == name:
- # logger.debug("Kernel installed")
+
+ logger.info("Kernel installed")
+
return True
+
else:
- # logger.debug("Kernel is not installed")
+ logger.info("Kernel is not installed")
return False
return False
@@ -923,12 +929,13 @@ def check_kernel_installed(name):
def wait_for_pacman_process():
-
+ logger.info("Waiting for pacman process")
timeout = 120
i = 0
while check_pacman_lockfile():
time.sleep(0.1)
- logger.debug("Pacman lockfile found .. waiting")
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Pacman lockfile found .. waiting")
i += 1
if i == timeout:
logger.info("Timeout reached")
@@ -949,6 +956,7 @@ def uninstall(self):
uninstall_cmd_str = None
event_log = []
+ # self.errors_found = False
if kernel_installed is True and kernel_headers_installed is True:
uninstall_cmd_str = [
@@ -964,9 +972,11 @@ def uninstall(self):
if kernel_installed == 0:
logger.info("Kernel is not installed, uninstall not required")
- self.kernel_state_queue.put((0, "uninstall", self.kernel.name))
+ self.kernel_state_queue.put((0, "uninstall"))
+ return
- logger.debug("Uninstall cmd = %s" % uninstall_cmd_str)
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Uninstall cmd = %s" % uninstall_cmd_str)
# check if kernel, and kernel header is actually installed
if uninstall_cmd_str is not None:
@@ -985,34 +995,35 @@ def uninstall(self):
uninstall_cmd_str,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- bufsize=1,
universal_newlines=True,
env=locale_env,
+ bufsize=1,
) as process:
while True:
if process.poll() is not None:
break
for line in process.stdout:
+ if logger.getEffectiveLevel() == 10:
+ print(line.strip())
+ # print(line.strip())
self.messages_queue.put(line)
- print(line.strip())
- event_log.append(line.lower().strip())
+ # event_log.append(line.lower().strip())
+ if (
+ "error" in line.lower().strip()
+ or "errors" in line.lower().strip()
+ ):
+ self.errors_found = True
+ break
# self.pacmanlog_queue.put(line)
# process_stdout_lst.append(line)
- time.sleep(0.3)
-
- self.errors_found = False
- for log in event_log:
- if "error" in log:
- self.errors_found = True
+ # time.sleep(0.1)
# query to check if kernel installed
if "headers" in uninstall_cmd_str:
if check_kernel_installed(self.kernel.name + "-headers") is True:
- self.kernel_state_queue.put(
- (1, "uninstall", self.kernel.name + "-headers")
- )
+ self.kernel_state_queue.put((1, "uninstall"))
event = (
"%s [ERROR]: Uninstall failed\n"
@@ -1022,7 +1033,7 @@ def uninstall(self):
self.messages_queue.put(event)
else:
- self.kernel_state_queue.put((0, "uninstall", self.kernel.name))
+ self.kernel_state_queue.put((0, "uninstall"))
event = (
"%s [INFO]: Uninstall completed\n"
@@ -1033,7 +1044,7 @@ def uninstall(self):
else:
if check_kernel_installed(self.kernel.name) is True:
- self.kernel_state_queue.put((1, "uninstall", self.kernel.name))
+ self.kernel_state_queue.put((1, "uninstall"))
event = (
"%s [ERROR]: Uninstall failed\n"
@@ -1043,7 +1054,7 @@ def uninstall(self):
self.messages_queue.put(event)
else:
- self.kernel_state_queue.put((0, "uninstall", self.kernel.name))
+ self.kernel_state_queue.put((0, "uninstall"))
event = (
"%s [INFO]: Uninstall completed\n"
@@ -1098,11 +1109,31 @@ def get_community_kernels(self):
version = line.split("Version :")[1].strip()
if line.startswith("Installed Size :"):
install_size = line.split("Installed Size :")[1].strip()
- if "MiB" in install_size:
- install_size = round(
- float(install_size.replace("MiB", "").strip())
- * 1.048576,
+ if logger.getEffectiveLevel() == 10:
+ logger.debug(
+ "%s installed kernel size = %s"
+ % (name, install_size)
)
+ if "MiB" in install_size:
+ if install_size.find(",") >= 0:
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Comma found inside install size")
+ install_size = round(
+ float(
+ install_size.replace(",", ".")
+ .strip()
+ .replace("MiB", "")
+ .strip()
+ )
+ * 1.048576,
+ 1,
+ )
+ else:
+ install_size = round(
+ float(install_size.replace("MiB", "").strip())
+ * 1.048576,
+ 1,
+ )
if line.startswith("Build Date :"):
build_date = line.split("Build Date :")[1].strip()
@@ -1130,6 +1161,16 @@ def get_community_kernels(self):
# =====================================================
def install_community_kernel(self):
try:
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Cleaning pacman cache, removing community packages")
+ if os.path.exists(pacman_cache):
+ for root, dirs, files in os.walk(pacman_cache):
+ for name in files:
+ for comm_kernel in community_kernels_dict.keys():
+ if name.startswith(comm_kernel):
+ if os.path.exists(os.path.join(root, name)):
+ os.remove(os.path.join(root, name))
+
error = False
install_cmd_str = [
"pacman",
@@ -1147,7 +1188,7 @@ def install_community_kernel(self):
" ".join(install_cmd_str),
)
- event_log = []
+ error = False
self.messages_queue.put(event)
@@ -1155,7 +1196,6 @@ def install_community_kernel(self):
install_cmd_str,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- bufsize=1,
universal_newlines=True,
env=locale_env,
) as process:
@@ -1163,22 +1203,49 @@ def install_community_kernel(self):
if process.poll() is not None:
break
for line in process.stdout:
- print(line.strip())
+ if logger.getEffectiveLevel() == 10:
+ print(line.strip())
+
self.messages_queue.put(line)
- event_log.append(line.lower().strip())
- time.sleep(0.3)
+ if "no space left on device" in line.lower().strip():
+ error = True
+ break
+ if "initcpio" in line.lower().strip():
+ if "image generation successful" in line.lower().strip():
+ error = False
+ break
+ if (
+ "installation finished. no error reported"
+ in line.lower().strip()
+ ):
+ error = False
+ break
+ if (
+ "error" in line.lower().strip()
+ or "errors" in line.lower().strip()
+ ):
+ error = True
+ break
+ time.sleep(0.1)
- for log in event_log:
- if "installation finished. no error reported." in log:
- error = False
- break
+ if error is True:
- if "error" in log:
- error = True
+ self.errors_found = True
+
+ error = True
+
+ GLib.idle_add(
+ show_mw,
+ self,
+ "System changes",
+ f"Kernel {self.action} failed\n"
+ f"There have been errors, please review the logs\n",
+ priority=GLib.PRIORITY_DEFAULT,
+ )
if check_kernel_installed(self.kernel.name) and error is False:
- self.kernel_state_queue.put((0, "install", self.kernel.name))
+ self.kernel_state_queue.put((0, "install"))
event = "%s [INFO]: Installation of %s completed\n" % (
datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
@@ -1188,7 +1255,7 @@ def install_community_kernel(self):
self.messages_queue.put(event)
else:
- self.kernel_state_queue.put((1, "install", self.kernel.name))
+ self.kernel_state_queue.put((1, "install"))
event = "%s [ERROR]: Installation of %s failed\n" % (
datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
@@ -1202,6 +1269,9 @@ def install_community_kernel(self):
self.kernel_state_queue.put(None)
except Exception as e:
logger.error("Exception in install_community_kernel(): %s " % e)
+ finally:
+ if os.path.exists(self.lockfile):
+ os.unlink(self.lockfile)
# =====================================================
@@ -1246,10 +1316,10 @@ def get_pacman_repos():
def get_installed_kernel_info(package_name):
+ logger.info("Installed kernel info - %s" % package_name)
query_str = ["pacman", "-Qi", package_name]
try:
-
process_kernel_query = subprocess.Popen(
query_str,
shell=False,
@@ -1264,13 +1334,35 @@ def get_installed_kernel_info(package_name):
for line in out.decode("utf-8").splitlines():
if line.startswith("Installed Size :"):
install_size = line.split("Installed Size :")[1].strip()
- if "MiB" in install_size:
- install_size = round(
- float(install_size.replace("MiB", "").strip()) * 1.048576,
+ if logger.getEffectiveLevel() == 10:
+ logger.debug(
+ "%s installed kernel size = %s"
+ % (package_name, install_size)
)
+ if "MiB" in install_size:
+ if install_size.find(",") >= 0:
+ logger.debug("Comma found inside install size")
+ install_size = round(
+ float(
+ install_size.replace(",", ".")
+ .strip()
+ .replace("MiB", "")
+ .strip()
+ )
+ * 1.048576,
+ 1,
+ )
+ else:
+ install_size = round(
+ float(install_size.replace("MiB", "").strip())
+ * 1.048576,
+ 1,
+ )
if line.startswith("Install Date :"):
install_date = line.split("Install Date :")[1].strip()
return install_size, install_date
+ else:
+ logger.error("Failed to get installed kernel info")
except Exception as e:
logger.error("Exception in get_installed_kernel_info(): %s" % e)
@@ -1281,6 +1373,7 @@ def get_installed_kernel_info(package_name):
def get_installed_kernels():
+ logger.info("Get installed kernels")
query_str = ["pacman", "-Q"]
installed_kernels = []
@@ -1305,6 +1398,10 @@ def get_installed_kernels():
package_name in supported_kernels_dict
or package_name in community_kernels_dict
):
+ if logger.getEffectiveLevel() == 10:
+ logger.debug(
+ "Installed linux package = %s" % package_name
+ )
install_size, install_date = get_installed_kernel_info(
package_name
)
@@ -1329,11 +1426,12 @@ def get_installed_kernels():
def get_active_kernel():
logger.info("Getting active Linux kernel")
- query_str = ["uname", "-rs"]
+ # cmd = ["uname", "-rs"]
+ cmd = ["kernel-install"]
try:
process_kernel_query = subprocess.Popen(
- query_str,
+ cmd,
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
@@ -1345,13 +1443,15 @@ def get_active_kernel():
if process_kernel_query.returncode == 0:
for line in out.decode("utf-8").splitlines():
if len(line.strip()) > 0:
- kernel = line.strip()
- _version = "-".join(kernel.split("-")[:-1])
- _type = kernel.split("-")[-1]
+ if "Kernel Version:" in line:
+ logger.info(
+ "Active kernel = %s"
+ % line.split("Kernel Version:")[1].strip()
+ )
+ return line.split("Kernel Version:")[1].strip()
+ else:
+ return "unknown"
- logger.info("Active kernel = %s" % kernel)
-
- return kernel
except Exception as e:
logger.error("Exception in get_active_kernel(): %s" % e)
@@ -1363,23 +1463,26 @@ def sync_package_db():
try:
sync_str = ["pacman", "-Sy"]
logger.info("Synchronizing pacman package databases")
- process_sync = subprocess.run(
- sync_str,
+
+ cmd = ["pacman", "-Sy"]
+
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Running cmd = %s" % cmd)
+
+ process = subprocess.Popen(
+ cmd,
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- timeout=process_timeout,
env=locale_env,
)
- if process_sync.returncode == 0:
+ out, err = process.communicate(timeout=600)
+
+ if process.returncode == 0:
return None
else:
- if process_sync.stdout:
- out = str(process_sync.stdout.decode("utf-8"))
- logger.error(out)
-
- return out
+ return out.decode("utf-8")
except Exception as e:
logger.error("Exception in sync_package_db(): %s" % e)
@@ -1434,8 +1537,16 @@ def get_boot_loader():
# ======================================================================
-def get_kernel_version(kernel):
- cmd = ["pacman", "-Qli", kernel]
+def get_kernel_modules_version(kernel, db):
+ cmd = None
+ if db == "local":
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Getting kernel module version from local pacman repo")
+ cmd = ["pacman", "-Qli", kernel]
+ if db == "package":
+ if logger.getEffectiveLevel() == 10:
+ logger.debug("Getting kernel module version from package cache file")
+ cmd = ["pacman", "-Qlip", kernel]
# pacman_kernel_version = None
kernel_modules_path = None
try:
@@ -1447,28 +1558,25 @@ def get_kernel_version(kernel):
stderr=subprocess.STDOUT,
timeout=process_timeout,
universal_newlines=True,
- bufsize=1,
env=locale_env,
)
if process.returncode == 0:
for line in process.stdout.splitlines():
- # if line.startswith("Version :"):
- # pacman_kernel_version = line.split("Version :")[1].strip()
- # print(pacman_kernel_version)
-
- if "/usr/lib/modules/" in line:
+ if "usr/lib/modules/" in line:
if "kernel" in line.split(" ")[1]:
kernel_modules_path = line.split(" ")[1]
break
if kernel_modules_path is not None:
return (
- kernel_modules_path.split("/usr/lib/modules/")[1]
+ kernel_modules_path.split("usr/lib/modules/")[1]
.strip()
.split("/kernel/")[0]
.strip()
)
+ else:
+ return None
else:
return None
@@ -1489,7 +1597,6 @@ def run_process(self):
self.cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- bufsize=1,
universal_newlines=True,
env=locale_env,
) as process:
@@ -1499,7 +1606,8 @@ def run_process(self):
for line in process.stdout:
self.messages_queue.put(line)
self.stdout_lines.append(line.lower().strip())
- print(line.strip())
+ if logger.getEffectiveLevel() == 10:
+ print(line.strip())
for log in self.stdout_lines:
if "error" in log or "errors" in log or "failed" in log:
@@ -1507,19 +1615,134 @@ def run_process(self):
error = True
if error is True:
- self.label_notify_revealer.set_text("%s failed" % " ".join(self.cmd))
- self.reveal_notify()
-
logger.error("%s failed" % " ".join(self.cmd))
- else:
- self.label_notify_revealer.set_text("%s completed" % " ".join(self.cmd))
- self.reveal_notify()
+ return True
+ else:
logger.info("%s completed" % " ".join(self.cmd))
+ return False
+
# time.sleep(0.3)
+# ======================================================================
+# KERNEL INITRD IMAGES TO AND FROM /BOOT
+# ======================================================================
+
+
+def kernel_initrd(self):
+ logger.info("Adding and removing kernel and initird images")
+ pkg_modules_version = None
+
+ if self.action == "install":
+ if self.source == "official":
+
+ pkg_modules_version = get_kernel_modules_version(
+ "%s/%s"
+ % (
+ pacman_cache,
+ "%s-x86_64%s" % (self.kernel.version, self.kernel.file_format),
+ ),
+ "package",
+ )
+
+ if self.source == "community":
+ pkg_modules_version = get_kernel_modules_version(
+ "%s/%s"
+ % (
+ pacman_cache,
+ "%s-%s-x86_64.pkg.tar.zst"
+ % (self.kernel.name, self.kernel.version),
+ ),
+ "package",
+ )
+
+ if pkg_modules_version is None:
+ logger.error("Failed to extract modules version from package")
+ return 1
+
+ logger.debug("Package modules version = %s" % pkg_modules_version)
+
+ # cmd = ["pacman", "-Qlp", "%s/" % pacman_cache]
+
+ if self.action == "install":
+ logger.info("Adding kernel and initrd images to /boot")
+ self.image = "images/48x48/akm-install.png"
+
+ if self.local_modules_version is not None:
+ for self.cmd in [
+ [
+ "kernel-install",
+ "remove",
+ self.local_modules_version,
+ ],
+ [
+ "kernel-install",
+ "add",
+ pkg_modules_version,
+ "/lib/modules/%s/vmlinuz" % pkg_modules_version,
+ ],
+ ]:
+ err = run_process(self)
+ if err is True:
+ return 1
+
+ else:
+ self.cmd = [
+ "kernel-install",
+ "add",
+ pkg_modules_version,
+ "/lib/modules/%s/vmlinuz" % pkg_modules_version,
+ ]
+ err = run_process(self)
+ if err is True:
+ return 1
+
+ else:
+ logger.info("Removing kernel and initrd images from /boot")
+ self.image = "images/48x48/akm-remove.png"
+ if self.local_modules_version is not None:
+ self.cmd = [
+ "kernel-install",
+ "remove",
+ self.local_modules_version,
+ ]
+ err = run_process(self)
+ if err is True:
+ return 1
+
+
+# ======================================================================
+# CHECK PACMAN REPO
+# ======================================================================
+def check_pacman_repo(repo):
+ logger.info("Checking %s pacman repository is configured" % repo)
+ cmd = ["pacman-conf", "-r", repo]
+
+ try:
+ with subprocess.Popen(
+ cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ universal_newlines=True,
+ env=locale_env,
+ ) as process:
+ while True:
+ if process.poll() is not None:
+ break
+ # for line in process.stdout:
+ # if logger.getEffectiveLevel() == 10:
+ # print(line.strip())
+
+ if process.returncode == 0:
+ return True
+ else:
+ return False
+ except Exception as e:
+ logger.error("Exception in check_pacman_repo(): %s" % e)
+
+
# ======================================================================
# UPDATE BOOTLOADER ENTRIES
# ======================================================================
@@ -1531,65 +1754,20 @@ def update_bootloader(self):
logger.info("Updating bootloader")
cmds = []
error = False
- self.stdout_lines = []
-
- if self.action == "install":
- image = "images/48x48/akm-install.png"
- if self.installed_kernel_version is not None:
- for self.cmd in [
- # ["kernel-install", "add-all", "--verbose"],
- [
- "kernel-install",
- "add",
- self.installed_kernel_version,
- "/lib/modules/%s/vmlinuz" % self.installed_kernel_version,
- ],
- [
- "kernel-install",
- "remove",
- self.installed_kernel_version,
- ],
- ]:
- run_process(self)
-
- else:
- # self.cmd = ["kernel-install", "add-all", "--verbose"].
- self.installed_kernel_version = get_kernel_version(self.kernel.name)
- self.cmd = [
- "kernel-install",
- "add",
- self.installed_kernel_version,
- "/lib/modules/%s/vmlinuz" % self.installed_kernel_version,
- ]
- run_process(self)
-
- else:
- image = "images/48x48/akm-remove.png"
- if self.installed_kernel_version is not None:
- self.cmd = [
- "kernel-install",
- "remove",
- self.installed_kernel_version,
- ]
- run_process(self)
+ stdout_lines = []
try:
-
- """
- kernel-install -add-all
- kernel-install remove $kernel_version
- this is for systems which do not have any pacman hooks in place
- useful for vanilla arch installs
- """
-
- self.label_notify_revealer.set_text("Updating bootloader %s" % self.bootloader)
- self.reveal_notify()
-
logger.info("Current bootloader = %s" % self.bootloader)
cmd = None
if self.bootloader == "grub":
+
+ self.label_notify_revealer.set_text(
+ "Updating bootloader %s" % self.bootloader
+ )
+ self.reveal_notify()
+
if self.bootloader_grub_cfg is not None:
cmd = ["grub-mkconfig", "-o", self.bootloader_grub_cfg]
else:
@@ -1604,12 +1782,48 @@ def update_bootloader(self):
elif self.bootloader == "systemd-boot":
# cmd = ["bootctl", "update"]
# graceful update systemd-boot
- cmd = ["bootctl", "--no-variables", "--graceful", "update"]
- event = "%s [INFO]: Running %s\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- " ".join(cmd),
+ # cmd = ["bootctl", "--no-variables", "--graceful", "update"]
+ # event = "%s [INFO]: Running %s\n" % (
+ # datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ # " ".join(cmd),
+ # )
+
+ self.label_notify_revealer.set_text(
+ "%s skipping bootloader update" % self.bootloader
)
+ self.reveal_notify()
+
+ event = (
+ "%s [INFO]: systemd-boot skipping bootloader update\n"
+ % datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
+ )
+
+ logger.info("systemd-boot skipping bootloader update")
+
self.messages_queue.put(event)
+
+ if (
+ self.restore is not None
+ and self.restore is False
+ and self.errors_found is False
+ ):
+ GLib.idle_add(
+ show_mw,
+ self,
+ "System changes",
+ f"Kernel {self.action} completed\n"
+ f"This window can now be closed",
+ priority=GLib.PRIORITY_DEFAULT,
+ )
+ # elif self.errors_found is True:
+ # GLib.idle_add(
+ # show_mw,
+ # self,
+ # "System changes",
+ # f"There have been errors, please review the logs\n",
+ # self.image,
+ # priority=GLib.PRIORITY_DEFAULT,
+ # )
else:
logger.error("Bootloader is empty / not supported")
@@ -1620,7 +1834,6 @@ def update_bootloader(self):
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
- bufsize=1,
universal_newlines=True,
env=locale_env,
) as process:
@@ -1630,7 +1843,9 @@ def update_bootloader(self):
for line in process.stdout:
self.stdout_lines.append(line.strip())
self.messages_queue.put(line)
- print(line.strip())
+ if logger.getEffectiveLevel() == 10:
+ print(line.strip())
+ # print(line.strip())
# time.sleep(0.3)
@@ -1648,20 +1863,13 @@ def update_bootloader(self):
)
self.messages_queue.put(event)
- logger.info("Linux packages have changed a reboot is recommended")
- event = "%s [INFO]: #### Linux packages have changed a reboot is recommended ####\n" % datetime.datetime.now().strftime(
- "%Y-%m-%d-%H-%M-%S"
- )
- self.messages_queue.put(event)
-
- if self.restore is False:
+ if self.restore is False and self.errors_found is False:
GLib.idle_add(
show_mw,
self,
"System changes",
f"Kernel {self.action} completed\n"
- f"This window can now be closed\n",
- image,
+ f"This window can now be closed",
priority=GLib.PRIORITY_DEFAULT,
)
else:
@@ -1677,14 +1885,14 @@ def update_bootloader(self):
)
self.messages_queue.put(event)
- if self.restore is False:
+ if self.restore is False and self.errors_found is False:
GLib.idle_add(
show_mw,
self,
"System changes",
f"Kernel {self.action} completed\n"
- f"This window can now be closed\n",
- image,
+ f"This window can now be closed",
+ self.image,
priority=GLib.PRIORITY_DEFAULT,
)
@@ -1708,29 +1916,13 @@ def update_bootloader(self):
self,
"System changes",
f"Kernel {self.action} failed .. attempting kernel restore\n"
- f"There have been errors, please review the logs\n",
- image,
+ f"There have been errors, please review the logs",
priority=GLib.PRIORITY_DEFAULT,
)
- else:
- logger.error("Bootloader update failed")
-
- GLib.idle_add(
- show_mw,
- self,
- "System changes",
- f"Kernel {self.action} failed\n"
- f"There have been errors, please review the logs\n",
- image,
- priority=GLib.PRIORITY_DEFAULT,
- )
- if os.path.exists(self.lockfile):
- os.unlink(self.lockfile)
- # else:
- # logger.error("Bootloader update cannot continue, failed to set command.")
except Exception as e:
logger.error("Exception in update_bootloader(): %s" % e)
+ finally:
if os.path.exists(self.lockfile):
os.unlink(self.lockfile)
@@ -1738,11 +1930,10 @@ def update_bootloader(self):
# ======================================================================
# SHOW MESSAGE WINDOW AFTER BOOTLOADER UPDATE
# ======================================================================
-def show_mw(self, title, msg, image):
+def show_mw(self, title, msg):
mw = MessageWindow(
title=title,
message=msg,
- image_path=image,
detailed_message=False,
transient_for=self,
)
diff --git a/usr/share/archlinux-kernel-manager/ui/FlowBox.py b/usr/share/archlinux-kernel-manager/ui/FlowBox.py
index 142cd5b..716d914 100644
--- a/usr/share/archlinux-kernel-manager/ui/FlowBox.py
+++ b/usr/share/archlinux-kernel-manager/ui/FlowBox.py
@@ -273,6 +273,8 @@ class FlowBox(Gtk.FlowBox):
)
message = None
title = None
+ downgrade = False
+ community_repo = False
if fn.check_pacman_lockfile() is False:
# switch widget is currently toggled off
@@ -284,38 +286,65 @@ class FlowBox(Gtk.FlowBox):
inst_kernel.version
> kernel.version.split("%s-" % inst_kernel.name)[1]
):
+ downgrade = True
title = "Downgrading %s kernel" % kernel.name
else:
+ downgrade = False
title = "Upgrading %s kernel" % kernel.name
break
if title is None:
- title = "Kernel install"
+ title = "Kernel installation"
if self.source == "community":
- message = "This will install %s-%s - Is this ok ?" % (
+ message = (
+ "Community kernel selected - this may break your system\n"
+ "Confirm the install of %s-%s"
+ % (
+ kernel.name,
+ kernel.version,
+ )
+ )
+
+ # check if the community pacman repo is configured
+ if fn.check_pacman_repo(kernel.repository) is True:
+ community_repo = True
+ else:
+ community_repo = False
+ fn.logger.error(
+ "%s pacman repo is not configured" % kernel.repository
+ )
+
+ elif self.source == "official":
+ message = "Confirm the install of %s-%s" % (
kernel.name,
kernel.version,
)
- elif self.source == "official":
- message = (
- "This will install %s - Is this ok ?" % kernel.version
- )
- message_window = FlowBoxMessageWindow(
- title=title,
- message=message,
- action="install",
- kernel=kernel,
- transient_for=self.manager_gui,
- textview=self.manager_gui.textview,
- textbuffer=self.manager_gui.textbuffer,
- switch=switch,
- source=self.source,
- manager_gui=self.manager_gui,
- )
- message_window.present()
+ if community_repo is False and self.source == "community":
+ mw = MessageWindow(
+ title="Cannot find %s pacman repo" % kernel.repository,
+ message="Enable the pacman repository then retry the installation",
+ transient_for=self.manager_gui,
+ detailed_message=False,
+ )
+ mw.present()
+ else:
+ message_window = FlowBoxMessageWindow(
+ title=title,
+ message=message,
+ action="install",
+ kernel=kernel,
+ transient_for=self.manager_gui,
+ textview=self.manager_gui.textview,
+ textbuffer=self.manager_gui.textbuffer,
+ switch=switch,
+ source=self.source,
+ manager_gui=self.manager_gui,
+ downgrade=downgrade,
+ )
+ message_window.present()
return True
# switch widget is currently toggled on
@@ -327,17 +356,18 @@ class FlowBox(Gtk.FlowBox):
if len(installed_kernels) > 1:
if self.source == "community":
- message = "This will remove %s-%s - Is this ok ?" % (
+ message = "Confirm the removal of %s-%s" % (
kernel.name,
kernel.version,
)
elif self.source == "official":
- message = (
- "This will remove %s - Is this ok ?" % kernel.version
+ message = "Confirm the removal of %s-%s" % (
+ kernel.name,
+ kernel.version,
)
message_window = FlowBoxMessageWindow(
- title="Kernel uninstall",
+ title="Kernel uninstallation",
message=message,
action="uninstall",
kernel=kernel,
@@ -347,6 +377,7 @@ class FlowBox(Gtk.FlowBox):
switch=switch,
source=self.source,
manager_gui=self.manager_gui,
+ downgrade=downgrade,
)
message_window.present()
return True
@@ -361,7 +392,6 @@ class FlowBox(Gtk.FlowBox):
title="Warning: Uninstall aborted",
message=f"You only have 1 kernel installed\n"
f"{kernel.name} {kernel.version} is currently active\n",
- image_path="images/48x48/akm-remove.png",
transient_for=self.manager_gui,
detailed_message=False,
)
@@ -378,7 +408,6 @@ class FlowBox(Gtk.FlowBox):
message="Pacman lockfile found, which indicates another pacman process is running",
transient_for=self.manager_gui,
detailed_message=False,
- image_path="images/48x48/akm-warning.png",
)
msg_win.present()
return True
@@ -496,6 +525,7 @@ class FlowBoxInstalled(Gtk.FlowBox):
switch=None,
source=None,
manager_gui=self.manager_gui,
+ downgrade=None,
)
message_window.present()
else:
@@ -507,7 +537,6 @@ class FlowBoxInstalled(Gtk.FlowBox):
title="Warning: Uninstall aborted",
message=f"You only have 1 kernel installed\n"
f"{installed_kernel.name} {installed_kernel.version}\n",
- image_path="images/48x48/akm-remove.png",
transient_for=self.manager_gui,
detailed_message=False,
)
@@ -526,6 +555,7 @@ class FlowBoxMessageWindow(Gtk.Window):
switch,
source,
manager_gui,
+ downgrade,
**kwargs,
):
super().__init__(**kwargs)
@@ -552,6 +582,7 @@ class FlowBoxMessageWindow(Gtk.Window):
self.action = action
self.switch = switch
self.source = source
+ self.downgrade = downgrade
vbox_flowbox_message = Gtk.Box.new(
orientation=Gtk.Orientation.VERTICAL, spacing=10
diff --git a/usr/share/archlinux-kernel-manager/ui/KernelStack.py b/usr/share/archlinux-kernel-manager/ui/KernelStack.py
index 765792a..2b4d385 100644
--- a/usr/share/archlinux-kernel-manager/ui/KernelStack.py
+++ b/usr/share/archlinux-kernel-manager/ui/KernelStack.py
@@ -465,7 +465,10 @@ class KernelStack:
label_warning = Gtk.Label(xalign=0, yalign=0)
label_warning.set_name("label_community_warning")
- if len(self.manager_gui.community_kernels) == 0:
+ if (
+ self.manager_gui.community_kernels is not None
+ and len(self.manager_gui.community_kernels) == 0
+ ):
label_warning.set_markup(
f"Cannot find any supported unofficial pacman repository's\n"
f"Add the Chaotic-AUR pacman repository to access Community based kernels"
@@ -529,7 +532,10 @@ class KernelStack:
# vbox_search_entry.append(search_entry_community)
# widget.append(vbox_search_entry)
- if len(self.manager_gui.community_kernels) > 0:
+ if (
+ self.manager_gui.community_kernels is not None
+ and len(self.manager_gui.community_kernels) > 0
+ ):
self.flowbox_community = FlowBox(
self.manager_gui.community_kernels,
self.manager_gui.active_kernel,
diff --git a/usr/share/archlinux-kernel-manager/ui/ManagerGUI.py b/usr/share/archlinux-kernel-manager/ui/ManagerGUI.py
index 4a2857e..d42e8aa 100644
--- a/usr/share/archlinux-kernel-manager/ui/ManagerGUI.py
+++ b/usr/share/archlinux-kernel-manager/ui/ManagerGUI.py
@@ -28,9 +28,6 @@ class ManagerGUI(Gtk.ApplicationWindow):
if self.app_version == "${app_version}":
self.app_version = "dev"
- fn.logger.info("Version = %s" % self.app_version)
- fn.logger.info("Distro = %s" % fn.distro.id())
-
self.set_title(app_name)
self.set_resizable(True)
self.set_default_size(950, 650)
@@ -50,10 +47,6 @@ class ManagerGUI(Gtk.ApplicationWindow):
self.splash_screen = SplashScreen(app_name)
- while self.default_context.pending():
- fn.time.sleep(0.1)
- self.default_context.iteration(True)
-
try:
fn.Thread(
target=self.wait_for_gui_load,
@@ -62,6 +55,10 @@ class ManagerGUI(Gtk.ApplicationWindow):
except Exception as e:
fn.logger.error(e)
+ while self.default_context.pending():
+ fn.time.sleep(0.1)
+ self.default_context.iteration(True)
+
hbox_notify_revealer = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, spacing=20
)
@@ -88,6 +85,9 @@ class ManagerGUI(Gtk.ApplicationWindow):
config_data = fn.setup_config(self)
+ fn.logger.info("Version = %s" % self.app_version)
+ fn.logger.info("Distro = %s" % fn.distro.id())
+
if "bootloader" in config_data.keys():
if config_data["bootloader"]["name"] is not None:
self.bootloader = config_data["bootloader"]["name"].lower()
@@ -185,11 +185,11 @@ class ManagerGUI(Gtk.ApplicationWindow):
self.vbox.append(self.notify_revealer)
self.installed_kernels = fn.get_installed_kernels()
+ if self.installed_kernels is not None:
+ fn.logger.info("Installed kernels = %s" % len(self.installed_kernels))
self.active_kernel = fn.get_active_kernel()
- fn.logger.info("Installed kernels = %s" % len(self.installed_kernels))
-
self.refresh_cache = False
self.refresh_cache = fn.get_latest_kernel_updates(self)
@@ -207,7 +207,6 @@ class ManagerGUI(Gtk.ApplicationWindow):
message=f"The specified Grub config file: {self.bootloader_grub_cfg} does not exist\n"
f"This will cause an issue when updating the bootloader\n"
f"Update the configuration file/use the Advanced Settings to change this\n",
- image_path="images/48x48/akm-error.png",
detailed_message=False,
transient_for=self,
)
@@ -222,7 +221,6 @@ class ManagerGUI(Gtk.ApplicationWindow):
message=f"Cannot select systemd-boot, UEFI boot mode is not available\n"
f"Update the configuration file\n"
f"Or use the Advanced Settings to change this\n",
- image_path="images/48x48/akm-warning.png",
detailed_message=False,
transient_for=self,
)
@@ -289,28 +287,26 @@ class ManagerGUI(Gtk.ApplicationWindow):
sync_err = fn.sync_package_db()
if sync_err is not None:
- fn.logger.error("Pacman db synchronization failed")
-
- print(
- "---------------------------------------------------------------------------"
- )
+ # fn.logger.error("Pacman db synchronization failed")
GLib.idle_add(
- self.show_sync_db_message_dialog,
+ self.show_sync_window,
sync_err,
priority=GLib.PRIORITY_DEFAULT,
)
+ return False
+
else:
fn.logger.info("Pacman DB synchronization completed")
+ return True
- def show_sync_db_message_dialog(self, sync_err):
+ def show_sync_window(self, sync_err):
mw = MessageWindow(
title="Error - Pacman db synchronization",
message=f"Pacman db synchronization failed\n"
f"Failed to run 'pacman -Syu'\n"
f"{sync_err}\n",
- image_path="images/48x48/akm-warning.png",
transient_for=self,
detailed_message=True,
)
@@ -367,25 +363,27 @@ class ManagerGUI(Gtk.ApplicationWindow):
self.start_get_kernels_threads()
- self.pacman_db_sync()
+ if self.pacman_db_sync() is False:
+ fn.logger.error("Pacman DB synchronization failed")
+ else:
- fn.logger.debug("Adding community kernels to UI")
+ fn.logger.debug("Adding community kernels to UI")
- try:
- thread_get_community_kernels = fn.Thread(
- name=fn.thread_get_community_kernels,
- target=fn.get_community_kernels,
- daemon=True,
- args=(self,),
- )
+ try:
+ thread_get_community_kernels = fn.Thread(
+ name=fn.thread_get_community_kernels,
+ target=fn.get_community_kernels,
+ daemon=True,
+ args=(self,),
+ )
- thread_get_community_kernels.start()
+ thread_get_community_kernels.start()
- except Exception as e:
- fn.logger.error("Exception in thread_get_community_kernels: %s" % e)
- finally:
- self.community_kernels = self.queue_community_kernels.get()
- self.queue_community_kernels.task_done()
+ except Exception as e:
+ fn.logger.error("Exception in thread_get_community_kernels: %s" % e)
+ finally:
+ self.community_kernels = self.queue_community_kernels.get()
+ self.queue_community_kernels.task_done()
self.installed_kernels = fn.get_installed_kernels()
@@ -507,36 +505,39 @@ class ManagerGUI(Gtk.ApplicationWindow):
# fn.logger.debug("Adding community kernels to UI")
# self.kernel_stack.add_community_kernels_to_stack(reload=False)
- self.queue_load_progress.put(1)
-
fn.logger.info("Starting pacman db synchronization")
- self.pacman_db_sync()
+ if self.pacman_db_sync() is False:
+ fn.logger.error("Pacman DB synchronization failed")
+ else:
- fn.logger.debug("Adding community kernels to UI")
-
- try:
- thread_get_community_kernels = fn.Thread(
- name=fn.thread_get_community_kernels,
- target=fn.get_community_kernels,
- daemon=True,
- args=(self,),
- )
-
- thread_get_community_kernels.start()
-
- except Exception as e:
- fn.logger.error("Exception in thread_get_community_kernels: %s" % e)
- finally:
- self.community_kernels = self.queue_community_kernels.get()
- self.queue_community_kernels.task_done()
fn.logger.debug("Adding community kernels to UI")
- self.kernel_stack.add_community_kernels_to_stack(reload=False)
+
+ try:
+ thread_get_community_kernels = fn.Thread(
+ name=fn.thread_get_community_kernels,
+ target=fn.get_community_kernels,
+ daemon=True,
+ args=(self,),
+ )
+
+ thread_get_community_kernels.start()
+
+ except Exception as e:
+ fn.logger.error("Exception in thread_get_community_kernels: %s" % e)
+ finally:
+ self.community_kernels = self.queue_community_kernels.get()
+ self.queue_community_kernels.task_done()
+
+ self.kernel_stack.add_community_kernels_to_stack(reload=False)
+
+ while self.default_context.pending():
+
+ self.default_context.iteration(True)
+
+ fn.time.sleep(0.3)
+
+ self.queue_load_progress.put(1)
fn.logger.debug("Adding installed kernels to UI")
self.kernel_stack.add_installed_kernels_to_stack(reload=False)
-
- while self.default_context.pending():
- self.default_context.iteration(True)
-
- fn.time.sleep(0.1)
diff --git a/usr/share/archlinux-kernel-manager/ui/MessageWindow.py b/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
index f1c37da..9e3ea1d 100644
--- a/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
+++ b/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
@@ -9,10 +9,10 @@ base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
class MessageWindow(Gtk.Window):
- def __init__(self, title, message, image_path, detailed_message, **kwargs):
+ def __init__(self, title, message, detailed_message, **kwargs):
super().__init__(**kwargs)
- # self.set_title(title=title)
+ self.set_title(title=title)
self.set_modal(modal=True)
self.set_resizable(False)
icon_name = "akm-tux"
@@ -34,14 +34,7 @@ class MessageWindow(Gtk.Window):
vbox_message = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=10)
vbox_message.set_name("vbox_flowbox_message")
- image = Gtk.Picture.new_for_filename(os.path.join(base_dir, image_path))
-
- image.set_content_fit(content_fit=Gtk.ContentFit.SCALE_DOWN)
- image.set_halign(Gtk.Align.START)
-
- hbox_image = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
-
- # hbox_image.append(image)
+ hbox_message = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
self.set_child(child=vbox_message)
@@ -65,26 +58,25 @@ class MessageWindow(Gtk.Window):
scrolled_window.set_child(textview)
- hbox_image.append(scrolled_window)
+ hbox_message.append(scrolled_window)
self.set_size_request(700, 500)
self.set_resizable(True)
else:
- label_message = Gtk.Label(xalign=0, yalign=0)
+ label_message = Gtk.Label(xalign=0.5, yalign=0.5)
label_message.set_markup("%s" % message)
label_message.set_name("label_flowbox_message")
- hbox_image.append(image)
- hbox_image.append(label_message)
+ hbox_message.append(label_message)
- vbox_message.append(hbox_image)
+ vbox_message.append(hbox_message)
button_ok = Gtk.Button.new_with_label("OK")
button_ok.set_size_request(100, 30)
button_ok.set_halign(Gtk.Align.END)
button_ok.connect("clicked", self.on_button_ok_clicked)
- hbox_buttons = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=20)
+ hbox_buttons = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
hbox_buttons.set_halign(Gtk.Align.END)
hbox_buttons.append(button_ok)
diff --git a/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py b/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py
index 188a820..0fa11e7 100644
--- a/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py
+++ b/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py
@@ -1,4 +1,5 @@
import random
+import shutil
import sys
import gi
import os
@@ -27,7 +28,7 @@ class ProgressWindow(Gtk.Window):
self.set_title(title=title)
self.set_modal(modal=True)
self.set_resizable(True)
- self.set_size_request(700, 300)
+ self.set_size_request(700, 250)
self.connect("close-request", self.on_close)
self.textview = textview
@@ -88,6 +89,8 @@ class ProgressWindow(Gtk.Window):
image_settings = None
+ self.local_modules_version = None
+
if action == "install":
image_settings = Gtk.Image.new_from_file(
os.path.join(base_dir, "images/48x48/akm-install.png")
@@ -105,16 +108,6 @@ class ProgressWindow(Gtk.Window):
% (self.kernel.name, self.kernel.version)
)
- # get kernel version from pacman
- self.installed_kernel_version = fn.get_kernel_version(self.kernel.name)
-
- if self.installed_kernel_version is not None:
- fn.logger.debug(
- "Installed kernel version = %s" % self.installed_kernel_version
- )
- else:
- fn.logger.debug("Nothing to remove .. previous kernel not installed")
-
image_settings.set_halign(Gtk.Align.START)
image_settings.set_icon_size(Gtk.IconSize.LARGE)
@@ -237,6 +230,7 @@ class ProgressWindow(Gtk.Window):
self.present()
self.linux_headers = None
+ self.restore_kernel = None
if (
self.source == "official"
@@ -244,6 +238,7 @@ class ProgressWindow(Gtk.Window):
or action == "uninstall"
and self.source == "official"
):
+ fn.logger.info("Official kernel selected")
if kernel.name == "linux":
self.linux_headers = "linux-headers"
if kernel.name == "linux-rt":
@@ -273,19 +268,17 @@ class ProgressWindow(Gtk.Window):
kernel.file_format,
),
]
-
- # in the event an install goes wrong, fallback and reinstall previous kernel
-
- if self.source == "official":
- self.restore_kernel = None
+ # in the event an install goes wrong, fallback and reinstall previous kernel
for inst_kernel in fn.get_installed_kernels():
if inst_kernel.name == self.kernel.name:
-
self.restore_kernel = inst_kernel
break
if self.restore_kernel:
+ self.local_modules_version = fn.get_kernel_modules_version(
+ self.restore_kernel.name, "local"
+ )
fn.logger.info("Restore kernel = %s" % self.restore_kernel.name)
fn.logger.info(
"Restore kernel version = %s" % self.restore_kernel.version
@@ -294,6 +287,9 @@ class ProgressWindow(Gtk.Window):
fn.logger.info("No previous %s kernel installed" % self.kernel.name)
else:
fn.logger.info("Community kernel, no kernel restore available")
+ self.local_modules_version = fn.get_kernel_modules_version(
+ self.kernel.name, "local"
+ )
if fn.check_pacman_lockfile() is False:
th_monitor_messages_queue = fn.threading.Thread(
@@ -416,7 +412,6 @@ class ProgressWindow(Gtk.Window):
mw = MessageWindow(
title="Pacman process running",
message="Pacman is busy processing a transaction .. please wait",
- image_path="images/48x48/akm-progress.png",
transient_for=self,
detailed_message=False,
)
@@ -430,7 +425,6 @@ class ProgressWindow(Gtk.Window):
mw = MessageWindow(
title="Pacman process running",
message="Pacman is busy processing a transaction .. please wait",
- image_path="images/48x48/akm-progress.png",
transient_for=self,
detailed_message=False,
)
@@ -442,15 +436,32 @@ class ProgressWindow(Gtk.Window):
def check_kernel_state(self):
returncode = None
- kernel = None
+ action = None
while True:
items = self.kernel_state_queue.get()
- try:
- if items is not None:
- returncode, action, kernel = items
+ if items is not None:
+ returncode, action = items
+
+ try:
+ if returncode == 0:
+ self.errors_found = False
+
+ fn.logger.info("Kernel %s completed" % action)
+
+ self.label_status.set_markup(
+ "Kernel %s completed"
+ % self.action
+ )
+ self.label_title.set_markup("Kernel %s completed" % action)
+
+ if fn.kernel_initrd(self) == 1:
+ self.errors_found = True
+ self.kernel_fail(action)
+ else:
+
+ fn.update_bootloader(self)
- if returncode == 0:
self.label_notify_revealer.set_text(
"Kernel %s completed" % action
)
@@ -458,170 +469,163 @@ class ProgressWindow(Gtk.Window):
fn.logger.info("Kernel %s completed" % action)
- if returncode == 1:
- self.errors_found = True
-
- self.label_notify_revealer.set_text("Kernel %s failed" % action)
- self.reveal_notify()
-
- fn.logger.error("Kernel %s failed" % action)
-
- event = "%s [ERROR]: Kernel %s failed\n" % (
- fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- action,
- )
- self.messages_queue.put(event)
+ self.spinner.set_spinning(False)
+ self.hbox_spinner.hide()
self.label_status.set_markup(
- "Kernel %s failed - see logs above"
- % action
+ "Kernel %s completed"
+ % self.action
+ )
+ self.label_title.set_markup(
+ "Kernel %s completed" % action
)
- # undo action here if action == install
-
- if (
- action == "install"
- and self.restore_kernel is not None
- and self.source == "official"
- ):
- event = (
- "%s [INFO]: Attempting to undo previous Linux package changes\n"
- % (
- fn.datetime.datetime.now().strftime(
- "%Y-%m-%d-%H-%M-%S"
- ),
- )
- )
-
- self.messages_queue.put(event)
-
- self.restore = True
- fn.logger.info(
- "Installation failed, attempting removal of previous Linux package changes"
- )
- self.set_title("Kernel installation failed")
-
- self.label_spinner_progress.set_markup(
- "Please wait restoring kernel %s"
- % self.restore_kernel.version
- )
-
- fn.uninstall(self)
-
- fn.logger.info(
- "Restoring previously installed kernel %s"
- % self.restore_kernel.version
- )
-
- self.official_kernels = [
- "%s/packages/l/%s/%s-%s-x86_64%s"
- % (
- fn.archlinux_mirror_archive_url,
- self.restore_kernel.name,
- self.restore_kernel.name,
- self.restore_kernel.version,
- ".pkg.tar.zst",
- ),
- "%s/packages/l/%s/%s-%s-x86_64%s"
- % (
- fn.archlinux_mirror_archive_url,
- self.linux_headers,
- self.linux_headers,
- self.restore_kernel.version,
- ".pkg.tar.zst",
- ),
- ]
- self.errors_found = False
- fn.install_archive_kernel(self)
- self.set_title("Kernel installation failed")
- self.label_status.set_markup(
- f"Kernel %s failed - see logs above\n"
- % action
- )
- else:
-
- self.spinner.set_spinning(False)
- self.hbox_spinner.hide()
-
- self.set_title("Kernel installation failed")
- self.label_title.set_markup("Install failed")
-
- #
- # self.label_progress_window_desc.set_markup(
- # f"This window can be now closed\n"
- # f"A reboot is recommended when Linux packages have changed"
- # )
-
- # break
- else:
- if (
- returncode == 0
- and "-headers" in kernel
- or action == "uninstall"
- or action == "install"
- and self.errors_found is False
- ):
-
- fn.update_bootloader(self)
- self.update_installed_list()
- self.update_official_list()
-
- if len(self.manager_gui.community_kernels) > 0:
- self.update_community_list()
-
- if self.restore == False:
- self.label_title.set_markup(
- "Kernel %s completed" % action
- )
-
- self.label_status.set_markup(
- "Kernel %s completed"
- % action
- )
-
- self.spinner.set_spinning(False)
- self.hbox_spinner.hide()
-
- self.label_progress_window_desc.set_markup(
- f"This window can be now closed\n"
- f"A reboot is recommended when Linux packages have changed"
- )
- else:
- self.label_title.set_markup(
- "Kernel %s failed" % action
- )
-
- self.label_status.set_markup(
- "Kernel %s failed"
- % action
- )
-
- self.spinner.set_spinning(False)
- self.hbox_spinner.hide()
-
- self.label_progress_window_desc.set_markup(
- f"This window can be now closed\n"
- f"Previous kernel restored due to failure\n"
- f"A reboot is recommended when Linux packages have changed"
- )
-
- # # else:
- # self.spinner.set_spinning(False)
- # self.hbox_spinner.hide()
- #
- # self.label_progress_window_desc.set_markup(
- # f"This window can be now closed\n"
- # f"A reboot is recommended when Linux packages have changed"
- # )
-
break
+
+ elif returncode == 1:
+ self.errors_found = True
+ self.kernel_fail(action)
+ else:
+ self.restore = None
+
+ fn.kernel_initrd(self)
+ fn.update_bootloader(self)
+
+ self.spinner.set_spinning(False)
+ self.hbox_spinner.hide()
+
+ if self.errors_found is True:
+
+ self.label_status.set_markup(
+ f"Kernel %s failed - see logs above\n"
+ % action
+ )
+
+ break
+ #
+ # else:
+ # break
+
except Exception as e:
fn.logger.error("Exception in check_kernel_state(): %s" % e)
+ finally:
+ self.kernel_state_queue.task_done()
+
if os.path.exists(self.lockfile):
os.unlink(self.lockfile)
- finally:
- self.kernel_state_queue.task_done()
+ self.update_installed_list()
+ self.update_official_list()
+
+ if len(self.manager_gui.community_kernels) > 0:
+ self.update_community_list()
+
+ while self.manager_gui.default_context.pending():
+ self.manager_gui.default_context.iteration(True)
+ fn.time.sleep(0.3)
+
+ self.spinner.set_spinning(False)
+ self.hbox_spinner.hide()
+
+ if self.errors_found is True:
+ event = (
+ "%s [ERROR]: Problems encountered with the last transaction, see logs"
+ % (fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),)
+ )
+ self.messages_queue.put(event)
+
+ else:
+ event = "%s [INFO]: A reboot is recommended" % (
+ fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ )
+ self.messages_queue.put(event)
+
+ if os.path.exists("/usr/lib/modules/build"):
+ shutil.rmtree("/usr/lib/modules/build", ignore_errors=True)
+
+ break
+
+ def kernel_fail(self, action):
+ self.errors_found = True
+ self.label_notify_revealer.set_text("Kernel %s failed" % action)
+ self.reveal_notify()
+
+ fn.logger.error("Kernel %s failed" % action)
+ self.label_title.set_markup("Kernel %s failed" % action)
+
+ self.label_status.set_markup(
+ "Kernel %s failed - see logs above"
+ % action
+ )
+ # self.action = "uninstall"
+ fn.logger.info(
+ "Installation failed, attempting removal of previous Linux package changes"
+ )
+ event = "%s [INFO]: Reverting package changes made\n" % (
+ fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ )
+
+ self.label_spinner_progress.set_markup(
+ "Please wait reverting package changes"
+ )
+
+ self.messages_queue.put(event)
+
+ self.label_title.set_markup("Kernel install failed")
+ self.action = "uninstall"
+ fn.uninstall(self)
+
+ if self.restore_kernel is not None and self.source == "official":
+ self.restore = True
+
+ self.label_spinner_progress.set_markup(
+ "Please wait restoring kernel %s" % self.restore_kernel.version
+ )
+
+ fn.logger.info(
+ "Restoring previously installed kernel %s" % self.restore_kernel.version
+ )
+
+ event = "%s [INFO]: Restoring previously installed kernel %s\n" % (
+ fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.restore_kernel.version,
+ )
+
+ self.messages_queue.put(event)
+
+ self.official_kernels = [
+ "%s/packages/l/%s/%s-%s-x86_64%s"
+ % (
+ fn.archlinux_mirror_archive_url,
+ self.restore_kernel.name,
+ self.restore_kernel.name,
+ self.restore_kernel.version,
+ ".pkg.tar.zst",
+ ),
+ "%s/packages/l/%s/%s-%s-x86_64%s"
+ % (
+ fn.archlinux_mirror_archive_url,
+ self.linux_headers,
+ self.linux_headers,
+ self.restore_kernel.version,
+ ".pkg.tar.zst",
+ ),
+ ]
+ self.errors_found = False
+ self.action = "install"
+ fn.install_archive_kernel(self)
+
+ self.label_title.set_markup("Kernel restored due to failure")
+ # elif self.source == "community":
+ # GLib.idle_add(
+ # fn.show_mw,
+ # self,
+ # "System changes",
+ # f"Kernel {self.action} failed\n"
+ # f"There have been errors, please review the logs\n",
+ # "images/48x48/akm-warning.png",
+ # priority=GLib.PRIORITY_DEFAULT,
+ # )
def update_installed_list(self):
self.manager_gui.installed_kernels = fn.get_installed_kernels()
diff --git a/usr/share/archlinux-kernel-manager/ui/SettingsWindow.py b/usr/share/archlinux-kernel-manager/ui/SettingsWindow.py
index 048cf2f..ae3b64c 100644
--- a/usr/share/archlinux-kernel-manager/ui/SettingsWindow.py
+++ b/usr/share/archlinux-kernel-manager/ui/SettingsWindow.py
@@ -491,7 +491,6 @@ class SettingsWindow(Gtk.Window):
mw = MessageWindow(
title="Legacy boot detected",
message="Cannot select systemd-boot, UEFI boot mode is not available",
- image_path="images/48x48/akm-warning.png",
transient_for=self,
detailed_message=False,
)
@@ -544,7 +543,6 @@ class SettingsWindow(Gtk.Window):
% self.text_entry_bootloader_file.get_buffer()
.get_text()
.strip(),
- image_path="images/48x48/akm-warning.png",
transient_for=self,
detailed_message=False,
)