Skip to content

Commit

Permalink
feat: use a custom grub message
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaohuiw42 committed Oct 16, 2024
1 parent d499e10 commit 8a66300
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
ostree (2024.6-1deepin4) unstable; urgency=medium

* use a custom grub message

-- wangzhaohui <[email protected]> Sat, 12 Oct 2024 15:21:52 +0800

ostree (2024.6-1deepin3) unstable; urgency=medium

* use last boot as default if GRUB_SAVEDEFAULT set in grub
Expand Down
127 changes: 127 additions & 0 deletions debian/patches/deepin-use-custom-grub-message.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c
index cbe7605..2015bf5 100644
--- a/src/libostree/ostree-bootloader-grub2.c
+++ b/src/libostree/ostree-bootloader-grub2.c
@@ -25,6 +25,8 @@
#include <sys/mount.h>

#include <string.h>
+#include <locale.h>
+#include <libintl.h>

// Written by bootupd
#define BOOTUPD_CONFIG "boot/bootupd-state.json"
@@ -166,6 +168,67 @@ _ostree_bootloader_grub2_get_name (OstreeBootloader *bootloader)
return "grub2";
}

+static char *
+ostree_deployment_get_time(OstreeSysroot *sysroot, OstreeDeployment *deployment)
+{
+ if (sysroot == NULL || deployment == NULL)
+ return NULL;
+
+ g_autofree char *deploy_path =
+ g_file_get_path(ostree_sysroot_get_deployment_directory(sysroot, deployment));
+
+ struct stat target_info;
+ if (stat(deploy_path, &target_info) != 0)
+ return NULL;
+
+ char deploy_time[20];
+ struct tm *tm_info;
+
+ tm_info = localtime(&target_info.st_mtime);
+ strftime(deploy_time, sizeof(deploy_time), "%Y/%m/%d %H:%M:%S", tm_info);
+
+ return g_strdup(deploy_time);
+}
+
+static const char *
+ostree_update_grub_boot_message(OstreeSysroot *sysroot, const char *stage_deploy_time,
+ const char *title, guint index)
+{
+ GPtrArray *deployments = sysroot->deployments;
+
+ if (index >= deployments->len)
+ return title;
+
+ g_autofree char *deploy_time = NULL;
+ /* When ostree has a staged deployment, a subprocess is spawned to call grub-mkconfig.
+ * However, the subprocess does not include the staged deployment in its deployment state,
+ * so we need to retrieve the deployment time from the OSTREE_STAGE_DEPLOY_TIME environment
+ * variable.
+ */
+ if (stage_deploy_time)
+ deploy_time = index == 0 ? g_strdup_printf("%s", stage_deploy_time)
+ : ostree_deployment_get_time(sysroot, deployments->pdata[index - 1]);
+ else
+ deploy_time = ostree_deployment_get_time(sysroot, deployments->pdata[index]);
+
+ if (deploy_time)
+ {
+ setlocale(LC_ALL, "");
+ bindtextdomain("ostree", "/usr/share/locale");
+ textdomain("ostree");
+
+ // remove substring " (ostree"
+ char *p = strstr(title, " (ostree");
+ if (p)
+ *p = '\0';
+
+ return index ? g_strdup_printf("%s %s (%s)", gettext("Roll back to"), title, deploy_time)
+ : g_strdup_printf("%s (%s)", title, deploy_time);
+ }
+
+ return title;
+}
+
/* This implementation is quite complex; see this issue for
* a starting point:
* https://github.com/ostreedev/ostree/issues/717
@@ -180,6 +243,7 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversio
static const char hardcoded_insmods[] = "insmod gzio\n";
const char *grub2_boot_device_id = g_getenv ("GRUB2_BOOT_DEVICE_ID");
const char *grub2_prepare_root_cache = g_getenv ("GRUB2_PREPARE_ROOT_CACHE");
+ const char *stage_deploy_time = g_getenv ("OSTREE_STAGE_DEPLOY_TIME");

/* We must have been called via the wrapper script */
g_assert (grub2_boot_device_id != NULL);
@@ -214,6 +278,7 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot, int bootversio

kernel = ostree_bootconfig_parser_get (config, "linux");

+ title = ostree_update_grub_boot_message(sysroot, stage_deploy_time, title, i);
quoted_title = g_shell_quote (title);
uuid = g_strdup_printf ("ostree-%u-%s", (guint)i, grub2_boot_device_id);
quoted_uuid = g_shell_quote (uuid);
@@ -285,6 +350,8 @@ typedef struct
{
const char *root;
const char *bootversion_str;
+ /* Used for child grub2-mkconfig to get deploy time of staged one */
+ const char *stage_deploy_time;
gboolean is_efi;
} Grub2ChildSetupData;

@@ -299,6 +366,8 @@ grub2_child_setup (gpointer user_data)
if (cdata->is_efi)
setenv ("_OSTREE_GRUB2_IS_EFI", "1", TRUE);

+ if (cdata->stage_deploy_time)
+ setenv ("OSTREE_STAGE_DEPLOY_TIME", cdata->stage_deploy_time, TRUE);
/* Everything below this is dealing with the chroot case; if
* we're not doing that, return early.
*/
@@ -425,6 +494,11 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader, int bootver
g_autofree char *bootversion_str = g_strdup_printf ("%u", (guint)bootversion);
cdata.bootversion_str = bootversion_str;
cdata.is_efi = self->is_efi;
+ /* The first deployment of new_deployments should be the staged one, pass its
+ deploy time to child grub-mkconfig to update grub boot message.
+ */
+ if (new_deployments->len)
+ cdata.stage_deploy_time = ostree_deployment_get_time (self->sysroot, new_deployments->pdata[0]);
/* Note in older versions of the grub2 package, this script doesn't even try
to be atomic; it just does:

3 changes: 2 additions & 1 deletion debian/patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ debian/test-sysroot-Skip-on-s390x-by-default.patch
debian/Skip-test-admin-deploy-uboot.sh-on-s390x.patch
deepin-deploy-when-root-is-overlay.patch
make-socket-callback-during-cleanup-into.patch
deepin-save-last-boot-as-defalt-for-grub.patch
deepin-save-last-boot-as-defalt-for-grub.patch
deepin-use-custom-grub-message.patch

0 comments on commit 8a66300

Please sign in to comment.