-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use a custom grub message if GRUB_OSTREE_CUSTOM_DESC is set in …
…grub
- Loading branch information
1 parent
4becf6b
commit 900320b
Showing
3 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
ostree (2024.6-1deepin3) unstable; urgency=medium | ||
|
||
* use a custom grub message if GRUB_OSTREE_CUSTOM_DESC is set in grub | ||
|
||
-- wangzhaohui <[email protected]> Sat, 12 Oct 2024 15:21:52 +0800 | ||
|
||
ostree (2024.6-1deepin2) unstable; urgency=medium | ||
|
||
* curl: Make socket callback during cleanup into no-op. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
Index: ostree/src/boot/grub2/grub2-15_ostree | ||
=================================================================== | ||
--- ostree.orig/src/boot/grub2/grub2-15_ostree | ||
+++ ostree/src/boot/grub2/grub2-15_ostree | ||
@@ -62,4 +62,8 @@ export GRUB2_BOOT_DEVICE_ID | ||
GRUB2_PREPARE_ROOT_CACHE="$(prepare_grub_to_access_device ${DEVICE})" | ||
export GRUB2_PREPARE_ROOT_CACHE | ||
|
||
+if [ "x${GRUB_OSTREE_CUSTOM_DESC}" = "xtrue" ] ; then | ||
+ export GRUB_OSTREE_CUSTOM_DESC=true | ||
+fi | ||
+ | ||
exec ostree admin instutil grub2-generate | ||
Index: ostree/src/libostree/ostree-bootloader-grub2.c | ||
=================================================================== | ||
--- ostree.orig/src/libostree/ostree-bootloader-grub2.c | ||
+++ ostree/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,78 @@ _ostree_bootloader_grub2_get_name (Ostre | ||
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, gboolean grub_in_thread, | ||
+ const char *title, guint index) | ||
+{ | ||
+ g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments(sysroot); | ||
+ | ||
+ 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 (grub_in_thread) | ||
+ { | ||
+ if (index == 0) | ||
+ { | ||
+ const char *stage_deploy_time = g_getenv("OSTREE_STAGE_DEPLOY_TIME"); | ||
+ deploy_time = stage_deploy_time ? g_strdup_printf("%s", stage_deploy_time) : stage_deploy_time; | ||
+ } | ||
+ else | ||
+ { | ||
+ 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 | ||
@@ -187,6 +261,8 @@ _ostree_bootloader_grub2_generate_config | ||
|
||
/* Passed from the parent */ | ||
gboolean is_efi = g_getenv ("_OSTREE_GRUB2_IS_EFI") != NULL; | ||
+ gboolean grub_custom_desc = g_getenv ("GRUB_OSTREE_CUSTOM_DESC") != NULL; | ||
+ gboolean grub_in_thread = g_getenv ("GRUB_MKCONFIG_IN_THREAD") != NULL; | ||
|
||
g_autoptr (GOutputStream) out_stream = g_unix_output_stream_new (target_fd, FALSE); | ||
|
||
@@ -214,6 +290,8 @@ _ostree_bootloader_grub2_generate_config | ||
|
||
kernel = ostree_bootconfig_parser_get (config, "linux"); | ||
|
||
+ if (grub_custom_desc) | ||
+ title = ostree_update_grub_boot_message(sysroot, grub_in_thread, 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 +363,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; | ||
|
||
@@ -294,11 +374,14 @@ grub2_child_setup (gpointer user_data) | ||
{ | ||
Grub2ChildSetupData *cdata = user_data; | ||
|
||
+ setenv ("GRUB_MKCONFIG_IN_THREAD", "true", TRUE); | ||
setenv ("_OSTREE_GRUB2_BOOTVERSION", cdata->bootversion_str, TRUE); | ||
/* We have to pass our state (whether or not we're using EFI) to the child */ | ||
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 +508,11 @@ _ostree_bootloader_grub2_write_config (O | ||
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: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters