Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use a custom grub message #6

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading