diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a43a531
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+usr/share/archlinux-kernel-manager/libs/__pycache__
+usr/share/archlinux-kernel-manager/ui/__pycache__
\ No newline at end of file
diff --git a/README.md b/README.md
index d8ed40d..a925ff4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Arch Linux Kernel Manager
-A GTK4 Python application used to install and remove Linux Kernels on an Arch based system.
+A GTK4 Python application which installs and removes Linux Kernels on Arch Linux based systems.
Installation and removal of Kernels is carried out using Pacman.
@@ -20,7 +20,7 @@ Both official and un-official community based Kernels are supported.
Since the ALA has a lot of kernel packages any versions found older than 2 years or more are ignored.
These kernels are considerably out of date and have shown to fail to install properly with issues related to missing modules.
-
+
## What happens if a kernel installation fails
@@ -43,11 +43,11 @@ Most of these are sourced from the [Chaotic AUR](https://aur.chaotic.cx)
See updating the [configuration file](#Adding-new-community-based-kernels) for adding new kernels.
-
+
# Installed kernels
-
+
# Progress window
@@ -75,13 +75,13 @@ By default, the application will use `bootctl` to distinguish which bootloader (
The bootloader settings can be overridden using the Advanced settings window.
Or you can manually update the configuration file (see the custom bootloader example).
-
+
## Latest kernel versions
Based on the latest information taken from the configured pacman mirrors.
-
+
# Default configuration file
@@ -156,12 +156,6 @@ Logs can be found inside `/var/log/archlinux-kernel-manager`
- python-psutil
-# Installing the application
-
-`wget https://raw.githubusercontent.com/DeltaCopy/archlinux-kernel-manager/main/PKGBUILD`
-
-`makepkg -si`
-
# Running the application
Run `akm` or `archlinux-kernel-manager` to launch the application.
diff --git a/usr/bin/archlinux-kernel-manager b/usr/bin/archlinux-kernel-manager
index c46d158..a62670d 100755
--- a/usr/bin/archlinux-kernel-manager
+++ b/usr/bin/archlinux-kernel-manager
@@ -4,49 +4,93 @@
# the polkit agent running on the desktop environment should prompt for root password
echo "---------------------------------------------------------------------------"
-echo "[INFO] Checking session"
-test $(whoami) == "root" && echo "[ERROR] Do not run this script as root." && exit 1
-test -z $DISPLAY && echo "[ERROR] DISPLAY variable is not set." && exit 1
+echo "[INFO]: Checking session"
+test $(whoami) == "root" && echo "[ERROR]: Do not run this script as root." && exit 1
+test -z $DISPLAY && echo "[ERROR]: DISPLAY variable is not set." && exit 1
# check session is either one of X11, Wayland or TTY
-session=$(loginctl show-session $(loginctl|grep $(whoami) | awk '{print $1}') -p Type | awk -F= '{print $2}' | grep "x11\|wayland\|tty")
+SESSION=$(loginctl show-session $(loginctl|grep $(whoami) | awk '{print $1}') -p Type | awk -F= '{print $2}' | grep "x11\|wayland\|tty")
+test -z "$SESSION" && echo "[ERROR]: Failed to verify session for user, SESSION = $SESSION" && exit 1
-test -z "$session" && echo "[ERROR] Failed to verify session for user." && exit 1
+XAUTHORITY=$(xauth info | awk -F"Authority file:" '{print $2}' | tr -d ' ')
+test -z "$XAUTHORITY" && echo "[ERROR]: XAUTHORIY file is not set" && exit 1
+test -s "$XAUTHORITY" || touch "$XAUTHORITY"
-xauth_file=$(xauth info | awk -F"Authority file:" '{print $2}' | tr -d ' ')
-test -s "$xauth_file" || touch "$xauth_file"
+XAUTH_HONORED=$(xauth info | awk -F"Changes honored:" '{print $2}' | tr -d ' ')
+test $XAUTH_HONORED = "yes" || echo "[ERROR]: Xauth changes honored = no, restart X server" || exit 1
-case "$session" in
- "wayland")
- # Wayland session, generate Xauth session cookie for $DISPLAY
- xauth gen $DISPLAY &> /dev/null
- echo "[INFO] Display = $DISPLAY"
- echo "[INFO] Session = $session"
+# GTK_A11Y=none - fixes the dbus-launch errors with GTK4
- test -z "$(xauth list)" || echo "[INFO] Xauth session = OK"
- ;;
- "x11")
- # X11 session, don't do anything here
- echo "[INFO] Display = $DISPLAY"
- echo "[INFO] Session = $session"
+echo "[INFO]: XAUTHORITY = $XAUTHORITY"
+echo "[INFO]: DBUS_SESSION_BUS_ADDRESS = $DBUS_SESSION_BUS_ADDRESS"
+echo "[INFO]: DESKTOP SESSION = $DESKTOP_SESSION"
- # just show msg on whether the Xauth session cookie is setup
- test -z "$(xauth list)" || echo "[INFO] Xauth session = OK"
- ;;
- "tty")
- # TTY session, as user may not use a display manager
- echo "[INFO] Display = $DISPLAY"
- echo "[INFO] Session = $session"
+function start_in_wayland() {
+ echo "[INFO]: Starting in Wayland session"
+ xauth gen $DISPLAY &> /dev/null
- test -z "$(xauth list)" || echo "[INFO] Xauth session = OK"
- ;;
- *)
- # anything here is an unknown session, most likely AKM will fail to load
- echo "[WARN] Continuing, but cannot verify session for user."
- ;;
-esac
+ case "$DESKTOP_SESSION" in
+ plasma | gnome)
+ pkexec env DISPLAY=$DISPLAY WAYLAND_DISPLAY="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" XAUTHORITY=$XAUTHORITY DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS GDK_BACKEND=x11 GTK_A11Y=none '/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py'
+ ;;
+ *)
+ pkexec env DISPLAY=$DISPLAY WAYLAND_DISPLAY="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" XAUTHORITY=$XAUTHORITY DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS GTK_A11Y=none '/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py'
+ ;;
+ esac
+}
+
+function start_in_x11() {
+ echo "[INFO]: Starting in X11 session"
+ pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS GTK_A11Y=none '/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py'
+}
+
+function start_in_tty() {
+ echo "[INFO]: Starting in TTY session"
+ pkexec '/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py'
+}
+
+case "$SESSION" in
+ "wayland")
+ # Wayland session, generate Xauth session cookie for $DISPLAY
+ echo "[INFO]: Display = $DISPLAY"
+ echo "[INFO]: Session = $SESSION"
+ start_in_wayland
+ ;;
+ "x11")
+ # X11 session, don't do anything here
+ echo "[INFO]: Display = $DISPLAY"
+ echo "[INFO]: Session = $SESSION"
+
+ # just show msg on whether the Xauth session cookie is setup
+ start_in_x11
+ ;;
+ "tty")
+ # TTY session, as user may not use a display manager
+ echo "[INFO]: Display = $DISPLAY"
+ echo "[INFO]: Session = $SESSION"
+
+ start_in_tty
+ ;;
+ *)
+ # anything here is an unknown session, most likely AKM will fail to load
+ echo "[INFO]: Display = $DISPLAY"
+ echo "[INFO]: Session could not be verified ... falling back to use XDG_SESSION_TYPE"
+
+ case "$XDG_SESSION_TYPE" in
+ "wayland")
+ start_in_wayland
+ ;;
+ "tty")
+ start_in_tty
+ ;;
+ "x11")
+ start_in_x11
+ ;;
+ *)
+ echo "[ERROR]: $XDG_SESSION_TYPE is empty, cannot continue"
+ exit 1
+ ;;
+ esac
+ ;;
+ esac
echo "---------------------------------------------------------------------------"
-
-echo "[INFO] Starting Arch Linux Kernel Manager"
-pkexec '/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py'
-
diff --git a/usr/share/archlinux-kernel-manager/akm.css b/usr/share/archlinux-kernel-manager/akm.css
index 5f2598d..69088b2 100644
--- a/usr/share/archlinux-kernel-manager/akm.css
+++ b/usr/share/archlinux-kernel-manager/akm.css
@@ -39,7 +39,7 @@ box#box_row{
box#hbox_kernel{
background-color: @theme_base_color;
padding-bottom: 8px;
- box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);
+ /*box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);*/
}
box#vbox_header{
@@ -53,7 +53,7 @@ box#vbox_header{
border-spacing: 5px;
font-weight: bold;
font-family: 'Noto Sans', 'Helvetica', sans-serif;
- box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);
+ /*box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);*/
}
box#hbox_warning{
@@ -156,15 +156,6 @@ button#button_uninstall_kernel{
padding: 10px 10px 10px 10px;
}
-.sidebar label:hover,
-.sidebar label:focus{
- font-weight: bold;
-}
-
-#hbox_stack_sidebar{
- box-shadow: rgba(33, 35, 38, 0.1) 0px 10px 10px -10px;
-}
-
#textview_log text{
background-color: #232627;
color: #fcfcfc;
diff --git a/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py b/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py
index eef0a83..88e2c83 100755
--- a/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py
+++ b/usr/share/archlinux-kernel-manager/archlinux-kernel-manager.py
@@ -17,7 +17,7 @@ base_dir = fn.os.path.dirname(fn.os.path.realpath(__file__))
app_name = "Arch Linux Kernel Manager"
app_version = "${app_version}"
app_name_dir = "archlinux-kernel-manager"
-app_id = "com.deltacopy.kernelmanager"
+app_id = "com.arcolinux.kernelmanager"
lock_file = "/tmp/akm.lock"
pid_file = "/tmp/akm.pid"
@@ -30,6 +30,7 @@ class Main(Gtk.Application):
default_context = GLib.MainContext.default()
win = self.props.active_window
+
if not win:
win = ManagerGUI(
application=self,
@@ -42,7 +43,6 @@ class Main(Gtk.Application):
# sourced from /usr/share/icons/hicolor/scalable/apps
win.set_icon_name("archlinux-kernel-manager-tux")
-
provider = Gtk.CssProvider.new()
css_file = Gio.file_new_for_path(base_dir + "/akm.css")
provider.load_from_file(css_file)
diff --git a/usr/share/archlinux-kernel-manager/images/364x408/akm-tux-splash.png b/usr/share/archlinux-kernel-manager/images/364x408/akm-tux-splash.png
deleted file mode 100644
index c1479a3..0000000
Binary files a/usr/share/archlinux-kernel-manager/images/364x408/akm-tux-splash.png and /dev/null differ
diff --git a/usr/share/archlinux-kernel-manager/images/48x48/akm-tux.png b/usr/share/archlinux-kernel-manager/images/48x48/akm-tux.png
index 5719279..8bdcdae 100644
Binary files a/usr/share/archlinux-kernel-manager/images/48x48/akm-tux.png and b/usr/share/archlinux-kernel-manager/images/48x48/akm-tux.png differ
diff --git a/usr/share/archlinux-kernel-manager/images/600x400/akm-tux-splash.png b/usr/share/archlinux-kernel-manager/images/600x400/akm-tux-splash.png
new file mode 100644
index 0000000..22815b9
Binary files /dev/null and b/usr/share/archlinux-kernel-manager/images/600x400/akm-tux-splash.png differ
diff --git a/usr/share/archlinux-kernel-manager/images/96x96/akm-tux.png b/usr/share/archlinux-kernel-manager/images/96x96/akm-tux.png
index 5a92094..1b136fe 100644
Binary files a/usr/share/archlinux-kernel-manager/images/96x96/akm-tux.png and b/usr/share/archlinux-kernel-manager/images/96x96/akm-tux.png differ
diff --git a/usr/share/archlinux-kernel-manager/libs/functions.py b/usr/share/archlinux-kernel-manager/libs/functions.py
index fdb57c9..d3ed11a 100644
--- a/usr/share/archlinux-kernel-manager/libs/functions.py
+++ b/usr/share/archlinux-kernel-manager/libs/functions.py
@@ -395,64 +395,67 @@ def write_cache():
# install from the ALA
def install_archive_kernel(self):
try:
- for pkg_archive_url in self.official_kernels:
- if self.errors_found is True:
- break
+ install_cmd_str = [
+ "pacman",
+ "-U",
+ self.official_kernels[0],
+ self.official_kernels[1],
+ "--noconfirm",
+ "--needed",
+ ]
- install_cmd_str = [
- "pacman",
- "-U",
- pkg_archive_url,
- "--noconfirm",
- "--needed",
- ]
+ wait_for_pacman_process()
- wait_for_pacman_process()
+ logger.info("Running %s" % install_cmd_str)
- logger.info("Running %s" % install_cmd_str)
+ event = "%s [INFO]: Running %s\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ " ".join(install_cmd_str),
+ )
- event = "%s [INFO]: Running %s\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- " ".join(install_cmd_str),
- )
+ event_log = []
+ self.messages_queue.put(event)
- event_log = []
- self.messages_queue.put(event)
+ with subprocess.Popen(
+ install_cmd_str,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ bufsize=1,
+ universal_newlines=True,
+ ) as process:
+ while True:
+ if process.poll() is not None:
+ break
+ for line in process.stdout:
+ print(line.strip())
+ self.messages_queue.put(line)
+ event_log.append(line.lower().strip())
- with subprocess.Popen(
- install_cmd_str,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- bufsize=1,
- universal_newlines=True,
- ) as process:
- while True:
- if process.poll() is not None:
- break
- for line in process.stdout:
- print(line.strip())
- self.messages_queue.put(line)
- event_log.append(line.lower().strip())
+ time.sleep(0.3)
- time.sleep(0.3)
+ error = None
- error = None
+ if (
+ "installation finished. no error reported."
+ or "initcpio image generation successful" in event_log
+ ):
+ error = False
- if "installation finished. no error reported." in event_log:
- error = False
- else:
+ 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
@@ -471,57 +474,49 @@ def install_archive_kernel(self):
break
- # query to check if kernel installed
- if "headers" in pkg_archive_url:
- if (
- check_kernel_installed(self.kernel.name + "-headers")
- and error is False
- ):
+ # query to check if kernel installed
- self.kernel_state_queue.put(
- (0, "install", self.kernel.name + "-headers")
- )
+ if check_kernel_installed(self.kernel.name + "-headers") and error is False:
- event = "%s [INFO]: Installation of %s-headers completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
+ self.kernel_state_queue.put((0, "install", self.kernel.name + "-headers"))
- self.messages_queue.put(event)
+ event = "%s [INFO]: Installation of %s-headers completed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.kernel.name,
+ )
- else:
- self.kernel_state_queue.put(
- (1, "install", self.kernel.name + "-headers")
- )
+ self.messages_queue.put(event)
- event = "%s [ERROR]: Installation of %s-headers failed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
+ else:
+ self.kernel_state_queue.put((1, "install", self.kernel.name + "-headers"))
- self.errors_found = True
- self.messages_queue.put(event)
+ event = "%s [ERROR]: Installation of %s-headers failed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.kernel.name,
+ )
- else:
- if check_kernel_installed(self.kernel.name) and error is False:
- self.kernel_state_queue.put((0, "install", self.kernel.name))
+ self.errors_found = True
+ self.messages_queue.put(event)
- event = "%s [INFO]: Installation of kernel %s completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
+ if check_kernel_installed(self.kernel.name) and error is False:
+ self.kernel_state_queue.put((0, "install", self.kernel.name))
- self.messages_queue.put(event)
+ event = "%s [INFO]: Installation of kernel %s completed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.kernel.name,
+ )
- else:
- self.kernel_state_queue.put((1, "install", self.kernel.name))
+ self.messages_queue.put(event)
- event = "%s [ERROR]: Installation of kernel %s failed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.kernel.name,
- )
+ else:
+ self.kernel_state_queue.put((1, "install", self.kernel.name))
- self.messages_queue.put(event)
+ 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)
# signal to say end reached
self.kernel_state_queue.put(None)
@@ -1117,80 +1112,76 @@ def get_community_kernels(self):
# =====================================================
def install_community_kernel(self):
try:
- for kernel in [self.kernel.name, "%s-headers" % self.kernel.name]:
- error = False
+ error = False
+ install_cmd_str = [
+ "pacman",
+ "-S",
+ "%s/%s" % (self.kernel.repository, self.kernel.name),
+ "%s/%s" % (self.kernel.repository, "%s-headers" % self.kernel.name),
+ "--noconfirm",
+ "--needed",
+ ]
- if self.errors_found is True:
+ logger.info("Running %s" % install_cmd_str)
+
+ event = "%s [INFO]: Running %s\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ " ".join(install_cmd_str),
+ )
+
+ event_log = []
+
+ self.messages_queue.put(event)
+
+ with subprocess.Popen(
+ install_cmd_str,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ bufsize=1,
+ universal_newlines=True,
+ ) as process:
+ while True:
+ if process.poll() is not None:
+ break
+ for line in process.stdout:
+ print(line.strip())
+ self.messages_queue.put(line)
+ event_log.append(line.lower().strip())
+
+ time.sleep(0.3)
+
+ for log in event_log:
+ if "installation finished. no error reported." in log:
+ error = False
break
- install_cmd_str = [
- "pacman",
- "-S",
- "%s/%s" % (self.kernel.repository, kernel),
- "--noconfirm",
- "--needed",
- ]
+ if "error" in log:
+ error = True
- logger.info("Running %s" % install_cmd_str)
+ if check_kernel_installed(self.kernel.name) and error is False:
+ logger.info("Kernel = installed")
- event = "%s [INFO]: Running %s\n" % (
+ self.kernel_state_queue.put((0, "install", self.kernel.name))
+
+ event = "%s [INFO]: Installation of %s completed\n" % (
datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- " ".join(install_cmd_str),
+ self.kernel.name,
)
- event_log = []
-
self.messages_queue.put(event)
- with subprocess.Popen(
- install_cmd_str,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- bufsize=1,
- universal_newlines=True,
- ) as process:
- while True:
- if process.poll() is not None:
- break
- for line in process.stdout:
- print(line.strip())
- self.messages_queue.put(line)
- event_log.append(line.lower().strip())
+ else:
+ logger.error("Kernel = install failed")
- time.sleep(0.3)
+ self.kernel_state_queue.put((1, "install", self.kernel.name))
- for log in event_log:
- if "installation finished. no error reported." in log:
- error = False
- break
+ event = "%s [ERROR]: Installation of %s failed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.kernel.name,
+ )
- if "error" in log:
- error = True
-
- if check_kernel_installed(kernel) and error == False:
- logger.info("Kernel = installed")
-
- self.kernel_state_queue.put((0, "install", kernel))
-
- event = "%s [INFO]: Installation of %s completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- kernel,
- )
-
- self.messages_queue.put(event)
-
- else:
- logger.error("Kernel = install failed")
-
- self.kernel_state_queue.put((1, "install", kernel))
-
- event = "%s [ERROR]: Installation of %s failed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- kernel,
- )
-
- self.errors_found = True
- self.messages_queue.put(event)
+ self.errors_found = True
+ self.messages_queue.put(event)
# signal to say end reached
self.kernel_state_queue.put(None)
@@ -1407,8 +1398,9 @@ def get_boot_loader():
def get_kernel_version(kernel):
- cmd = ["pacman", "-Q", kernel]
-
+ cmd = ["pacman", "-Qli", kernel]
+ # pacman_kernel_version = None
+ kernel_modules_path = None
try:
logger.debug("Running %s" % " ".join(cmd))
process = subprocess.run(
@@ -1423,12 +1415,68 @@ def get_kernel_version(kernel):
if process.returncode == 0:
for line in process.stdout.splitlines():
- print(line.strip())
- return line.split(" ")[1]
+ # if line.startswith("Version :"):
+ # pacman_kernel_version = line.split("Version :")[1].strip()
+ # print(pacman_kernel_version)
+
+ 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]
+ .strip()
+ .split("/kernel/")[0]
+ .strip()
+ )
+ else:
+ return None
+
except Exception as e:
logger.error("Exception in get_kernel_version(): %s" % e)
+def run_process(self):
+ error = False
+
+ logger.debug("Running process = %s" % " ".join(self.cmd))
+ with subprocess.Popen(
+ self.cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ bufsize=1,
+ universal_newlines=True,
+ ) as process:
+ while True:
+ if process.poll() is not None:
+ break
+ for line in process.stdout:
+ self.messages_queue.put(line)
+ self.stdout_lines.append(line.lower().strip())
+ print(line.strip())
+
+ for log in self.stdout_lines:
+ if "error" in log or "errors" in log:
+ self.errors_found = True
+
+ 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()
+
+ logger.info("%s completed" % " ".join(self.cmd))
+
+ # time.sleep(0.3)
+
+
# ======================================================================
# UPDATE BOOTLOADER ENTRIES
# ======================================================================
@@ -1437,14 +1485,30 @@ def get_kernel_version(kernel):
# grub - grub-mkconfig /boot/grub/grub.cfg
# systemd-boot - bootctl update
def update_bootloader(self):
- cmd = None
+ cmds = []
+ error = False
+ self.stdout_lines = []
if self.action == "install":
image = "images/48x48/akm-install.png"
- cmd = ["kernel-install", "add-all"]
+
+ if self.installed_kernel_version is not None:
+
+ for self.cmd in [
+ ["kernel-install", "add-all"],
+ ["kernel-install", "remove", self.installed_kernel_version],
+ ]:
+ run_process(self)
+
+ else:
+ self.cmd = ["kernel-install", "add-all"]
+ run_process(self)
+
else:
image = "images/48x48/akm-remove.png"
- cmd = ["kernel-install", "remove", self.installed_kernel_version]
+ if self.installed_kernel_version is not None:
+ self.cmd = ["kernel-install", "remove", self.installed_kernel_version]
+ run_process(self)
try:
@@ -1460,17 +1524,35 @@ def update_bootloader(self):
logger.info("Current bootloader = %s" % self.bootloader)
- if cmd is not None:
- stdout_lines = []
+ cmd = None
+
+ if self.bootloader == "grub":
+ if self.bootloader_grub_cfg is not None:
+ cmd = ["grub-mkconfig", "-o", self.bootloader_grub_cfg]
+ else:
+ logger.error("Bootloader grub config file not specified")
+
event = "%s [INFO]: Running %s\n" % (
datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
" ".join(cmd),
)
-
self.messages_queue.put(event)
- logger.info("Running %s" % " ".join(cmd))
+ 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),
+ )
+ self.messages_queue.put(event)
+ else:
+ logger.error("Bootloader is empty / not supported")
+ if cmd is not None:
+ self.stdout_lines = []
+ logger.info("Running %s" % " ".join(cmd))
with subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
@@ -1482,183 +1564,105 @@ def update_bootloader(self):
if process.poll() is not None:
break
for line in process.stdout:
+ self.stdout_lines.append(line.strip())
self.messages_queue.put(line)
- stdout_lines.append(line.lower().strip())
print(line.strip())
# time.sleep(0.3)
- error = False
+ if process.returncode == 0:
+ self.label_notify_revealer.set_text(
+ "Bootloader %s updated" % self.bootloader
+ )
+ self.reveal_notify()
- for log in stdout_lines:
- if "error" in log or "errors" in log:
+ logger.info("%s update completed" % self.bootloader)
- # event = (
- # "%s [ERROR]: Errors have been encountered during installation\n"
- # % (datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"))
- # )
- #
- # self.messages_queue.put(event)
+ event = "%s [INFO]: %s update completed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.bootloader,
+ )
+ self.messages_queue.put(event)
- self.errors_found = True
+ 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)
- error = True
+ if self.restore 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,
+ priority=GLib.PRIORITY_DEFAULT,
+ )
+ else:
+ if (
+ "Skipping"
+ or "same boot loader version in place already." in stdout_lines
+ ):
+ logger.info("%s update completed" % self.bootloader)
- if error is True:
- self.label_notify_revealer.set_text("%s failed" % " ".join(cmd))
- self.reveal_notify()
+ event = "%s [INFO]: %s update completed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.bootloader,
+ )
+ self.messages_queue.put(event)
- logger.error("%s failed" % " ".join(cmd))
- else:
- self.label_notify_revealer.set_text("%s completed" % " ".join(cmd))
- self.reveal_notify()
+ if self.restore 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,
+ priority=GLib.PRIORITY_DEFAULT,
+ )
- logger.info("%s completed" % " ".join(cmd))
-
- if self.bootloader == "grub":
- if self.bootloader_grub_cfg is not None:
- cmd = ["grub-mkconfig", "-o", self.bootloader_grub_cfg]
else:
- logger.error("Bootloader grub config file not specified")
+ self.label_notify_revealer.set_text(
+ "Bootloader %s update failed" % self.bootloader
+ )
+ self.reveal_notify()
- event = "%s [INFO]: Running %s\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- " ".join(cmd),
- )
- self.messages_queue.put(event)
+ event = "%s [ERROR]: %s update failed\n" % (
+ datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
+ self.bootloader,
+ )
- 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),
- )
- self.messages_queue.put(event)
- else:
- logger.error("Bootloader is empty / not supported")
+ logger.error("%s update failed" % self.bootloader)
+ logger.error(str(stdout_lines))
+ self.messages_queue.put(event)
- if cmd is not None:
- stdout_lines = []
- logger.info("Running %s" % " ".join(cmd))
- with subprocess.Popen(
- cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- bufsize=1,
- universal_newlines=True,
- ) as process:
- while True:
- if process.poll() is not None:
- break
- for line in process.stdout:
- stdout_lines.append(line.strip())
- self.messages_queue.put(line)
- print(line.strip())
+ GLib.idle_add(
+ show_mw,
+ self,
+ "System changes",
+ f"Kernel {self.action} failed .. attempting kernel restore\n"
+ f"There have been errors, please review the logs\n",
+ image,
+ priority=GLib.PRIORITY_DEFAULT,
+ )
- # time.sleep(0.3)
-
- if process.returncode == 0:
- self.label_notify_revealer.set_text(
- "Bootloader %s updated" % self.bootloader
- )
- self.reveal_notify()
-
- logger.info("%s update completed" % self.bootloader)
-
- event = "%s [INFO]: %s update completed\n" % (
- datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- self.bootloader,
- )
- 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:
- GLib.idle_add(
- show_mw,
- self,
- "System changes",
- f"Kernel {self.action} completed\n"
- f"This window can now be closed\n",
- image,
- priority=GLib.PRIORITY_DEFAULT,
- )
- else:
- if (
- "Skipping"
- or "same boot loader version in place already."
- in stdout_lines
- ):
- logger.info("%s update completed" % self.bootloader)
-
- event = "%s [INFO]: %s update completed\n" % (
- datetime.datetime.now().strftime(
- "%Y-%m-%d-%H-%M-%S"
- ),
- self.bootloader,
- )
- self.messages_queue.put(event)
-
- if self.restore 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,
- priority=GLib.PRIORITY_DEFAULT,
- )
-
- else:
- self.label_notify_revealer.set_text(
- "Bootloader %s update failed" % self.bootloader
- )
- self.reveal_notify()
-
- event = "%s [ERROR]: %s update failed\n" % (
- datetime.datetime.now().strftime(
- "%Y-%m-%d-%H-%M-%S"
- ),
- self.bootloader,
- )
-
- logger.error("%s update failed" % self.bootloader)
- logger.error(str(stdout_lines))
- self.messages_queue.put(event)
-
- GLib.idle_add(
- show_mw,
- self,
- "System changes",
- f"Kernel {self.action} failed .. attempting kernel restore\n"
- f"There have been errors, please review the logs\n",
- image,
- 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,
- )
else:
- logger.error("Bootloader update cannot continue, failed to set command.")
+ 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,
+ )
+ # else:
+ # logger.error("Bootloader update cannot continue, failed to set command.")
except Exception as e:
logger.error("Exception in update_bootloader(): %s" % e)
diff --git a/usr/share/archlinux-kernel-manager/ui/AboutDialog.py b/usr/share/archlinux-kernel-manager/ui/AboutDialog.py
index 40600fd..6c9ca12 100644
--- a/usr/share/archlinux-kernel-manager/ui/AboutDialog.py
+++ b/usr/share/archlinux-kernel-manager/ui/AboutDialog.py
@@ -13,14 +13,13 @@ class AboutDialog(Gtk.AboutDialog):
def __init__(self, manager_gui, **kwargs):
super().__init__(**kwargs)
- website = "https://github.com/DeltaCopy/archlinux-kernel-manager"
- authors = ["fennec (DeltaCopy)"]
+ website = "http://arcolinux.info/"
+ authors = ["Erik Dubois", "Fennec"]
program_name = "Arch Linux Kernel Manager"
comments = (
f"Add/Remove Officially supported Linux kernels on Arch based systems\n"
f"Powered by the Arch Linux Archive (a.k.a ALA)\n"
f"Community based Linux kernels are also supported\n"
- f"This application matches your system theme !\n"
f"Developed in Python with GTK 4\n"
)
@@ -40,7 +39,7 @@ class AboutDialog(Gtk.AboutDialog):
tux_icon = Gdk.Texture.new_from_file(
file=Gio.File.new_for_path(
- os.path.join(base_dir, "images/364x408/akm-tux-splash.png")
+ os.path.join(base_dir, "images/96x96/akm-tux.png")
)
)
diff --git a/usr/share/archlinux-kernel-manager/ui/FlowBox.py b/usr/share/archlinux-kernel-manager/ui/FlowBox.py
index 99fdfc6..6051e7c 100644
--- a/usr/share/archlinux-kernel-manager/ui/FlowBox.py
+++ b/usr/share/archlinux-kernel-manager/ui/FlowBox.py
@@ -107,26 +107,29 @@ class FlowBox(Gtk.FlowBox):
) == "{}-{}".format(cache.name, cache.version):
installed = True
- if (
- cache.name == installed_kernel.name
- and cache.version > installed_kernel.version
- ):
- fn.logger.info(
- "Kernel upgrade available - %s %s"
- % (cache.name, cache.version)
- )
-
- tux_icon = Gtk.Picture.new_for_file(
- file=Gio.File.new_for_path(
- os.path.join(base_dir, "images/48x48/akm-update.png")
+ if cache.name == installed_kernel.name:
+ if (
+ cache.version > installed_kernel.version
+ or cache.version != installed_kernel.version
+ ):
+ fn.logger.info(
+ "Kernel upgrade available - %s %s"
+ % (cache.name, cache.version)
)
- )
- tux_icon.set_can_shrink(True)
- label_kernel_name.set_markup(
- "*%s %s %s"
- % (cache.name, cache.version, cache.repository)
- )
+ tux_icon = Gtk.Picture.new_for_file(
+ file=Gio.File.new_for_path(
+ os.path.join(
+ base_dir, "images/48x48/akm-update.png"
+ )
+ )
+ )
+ tux_icon.set_can_shrink(True)
+
+ label_kernel_name.set_markup(
+ "*%s %s %s"
+ % (cache.name, cache.version, cache.repository)
+ )
if installed is True:
switch_kernel.set_state(True)
diff --git a/usr/share/archlinux-kernel-manager/ui/MessageWindow.py b/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
index 6ed7915..f1c37da 100644
--- a/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
+++ b/usr/share/archlinux-kernel-manager/ui/MessageWindow.py
@@ -15,6 +15,8 @@ class MessageWindow(Gtk.Window):
# self.set_title(title=title)
self.set_modal(modal=True)
self.set_resizable(False)
+ icon_name = "akm-tux"
+ self.set_icon_name(icon_name)
header_bar = Gtk.HeaderBar()
header_bar.set_show_title_buttons(True)
@@ -57,7 +59,7 @@ class MessageWindow(Gtk.Window):
msg_buffer.insert(
msg_buffer.get_end_iter(),
"Event timestamp = %s\n"
- % fn.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ % fn.datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
)
msg_buffer.insert(msg_buffer.get_end_iter(), "%s\n" % message)
@@ -82,7 +84,7 @@ class MessageWindow(Gtk.Window):
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=10)
+ hbox_buttons = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=20)
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 e09e0ad..6a75fbb 100644
--- a/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py
+++ b/usr/share/archlinux-kernel-manager/ui/ProgressWindow.py
@@ -94,8 +94,15 @@ 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)
+ # 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)
@@ -418,8 +425,9 @@ class ProgressWindow(Gtk.Window):
)
mw.present()
- else:
- self.destroy()
+
+ return True
+ return False
def check_kernel_state(self):
returncode = None
@@ -439,12 +447,6 @@ class ProgressWindow(Gtk.Window):
fn.logger.info("Kernel %s completed" % action)
- event = "%s [INFO]: Kernel %s completed\n" % (
- fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"),
- action,
- )
- self.messages_queue.put(event)
-
if returncode == 1:
self.errors_found = True
diff --git a/usr/share/archlinux-kernel-manager/ui/SplashScreen.py b/usr/share/archlinux-kernel-manager/ui/SplashScreen.py
index b945ca2..f5799dd 100644
--- a/usr/share/archlinux-kernel-manager/ui/SplashScreen.py
+++ b/usr/share/archlinux-kernel-manager/ui/SplashScreen.py
@@ -2,7 +2,7 @@ import gi
import libs.functions as fn
gi.require_version("Gtk", "4.0")
-from gi.repository import Gtk, Gio, GLib, GdkPixbuf, GObject, Gdk
+from gi.repository import Gtk, Gio
base_dir = fn.os.path.abspath(fn.os.path.join(fn.os.path.dirname(__file__), ".."))
@@ -12,15 +12,18 @@ class SplashScreen(Gtk.Window):
super().__init__(**kwargs)
self.set_decorated(False)
self.set_resizable(False)
+ self.set_default_size(600, 400)
+
self.set_modal(True)
self.set_title(app_name)
self.set_icon_name("archlinux-kernel-manager-tux")
tux_icon = Gtk.Picture.new_for_file(
file=Gio.File.new_for_path(
- fn.os.path.join(base_dir, "images/364x408/akm-tux-splash.png")
+ fn.os.path.join(base_dir, "images/600x400/akm-tux-splash.png")
)
)
+
tux_icon.set_content_fit(content_fit=Gtk.ContentFit.FILL)
self.set_child(child=tux_icon)