From 5edfdd5dc8806fb6520ee698f42d269143ad5c45 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 6 Dec 2016 17:23:28 +1100 Subject: ui/ncurses: Add status log UI Currently, status messages from the server are displayed in a single line at the bottom of the main menu UI, and are lost once a new status is reported. This change adds a facility for the UI to collect and display the status messages from the server, in a dedicated UI screen. This allows a user to look back through the discovery & boot process. Signed-off-by: Jeremy Kerr Signed-off-by: Samuel Mendoza-Jonas --- ui/ncurses/Makefile.am | 5 +- ui/ncurses/nc-cui-help.c | 2 + ui/ncurses/nc-cui.c | 39 +++++++++++++--- ui/ncurses/nc-cui.h | 3 ++ ui/ncurses/nc-menu.c | 3 ++ ui/ncurses/nc-statuslog.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ ui/ncurses/nc-statuslog.h | 35 ++++++++++++++ 7 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 ui/ncurses/nc-statuslog.c create mode 100644 ui/ncurses/nc-statuslog.h (limited to 'ui/ncurses') diff --git a/ui/ncurses/Makefile.am b/ui/ncurses/Makefile.am index 265ae69..feec51d 100644 --- a/ui/ncurses/Makefile.am +++ b/ui/ncurses/Makefile.am @@ -49,7 +49,10 @@ ui_ncurses_libpbnc_la_SOURCES = \ ui/ncurses/nc-add-url.h \ ui/ncurses/nc-add-url-help.c \ ui/ncurses/nc-subset.c \ - ui/ncurses/nc-subset.h + ui/ncurses/nc-subset.h \ + ui/ncurses/nc-statuslog.c \ + ui/ncurses/nc-statuslog.h + sbin_PROGRAMS += ui/ncurses/petitboot-nc diff --git a/ui/ncurses/nc-cui-help.c b/ui/ncurses/nc-cui-help.c index 0482830..7d97ba5 100644 --- a/ui/ncurses/nc-cui-help.c +++ b/ui/ncurses/nc-cui-help.c @@ -18,6 +18,8 @@ To make changes to the system configuration, type C (configure).\n\ \n\ To set the language for the petitboot interface, type L (language).\n\ \n\ +To view the log of status messages from the discovery process, type G (log).\n\ +\n\ To find new or updated boot options on the system, select the 'Rescan devices' \ option.\n\ \n\ diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index a6537cb..86515bc 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -42,6 +42,7 @@ #include "nc-sysinfo.h" #include "nc-lang.h" #include "nc-helpscreen.h" +#include "nc-statuslog.h" #include "nc-subset.h" extern const struct help_text main_menu_help_text; @@ -335,6 +336,19 @@ void cui_show_lang(struct cui *cui) cui_set_current(cui, lang_screen_scr(cui->lang_screen)); } +static void cui_statuslog_exit(struct cui *cui) +{ + cui_set_current(cui, &cui->main->scr); + talloc_free(cui->statuslog_screen); + cui->statuslog_screen = NULL; +} + +void cui_show_statuslog(struct cui *cui) +{ + cui->statuslog_screen = statuslog_screen_init(cui, cui_statuslog_exit); + cui_set_current(cui, statuslog_screen_scr(cui->statuslog_screen)); +} + static void cui_add_url_exit(struct cui *cui) { cui_set_current(cui, &cui->main->scr); @@ -698,6 +712,8 @@ static void cui_update_status(struct status *status, void *arg) { struct cui *cui = cui_from_arg(arg); + statuslog_append_steal(cui, cui->statuslog, status); + nc_scr_status_printf(cui->current, "%s: %s", status->type == STATUS_ERROR ? @@ -825,6 +841,12 @@ static int menu_lang_execute(struct pmenu_item *item) return 0; } +static int menu_statuslog_execute(struct pmenu_item *item) +{ + cui_show_statuslog(cui_from_item(item)); + return 0; +} + static int menu_reinit_execute(struct pmenu_item *item) { if (cui_from_item(item)->client) @@ -849,7 +871,7 @@ static struct pmenu *main_menu_init(struct cui *cui) int result; bool lockdown = lockdown_active(); - m = pmenu_init(cui, 7, cui_on_exit); + m = pmenu_init(cui, 8, cui_on_exit); if (!m) { pb_log("%s: failed\n", __func__); return NULL; @@ -861,7 +883,7 @@ static struct pmenu *main_menu_init(struct cui *cui) "Petitboot (" PACKAGE_VERSION ")"); m->scr.frame.rtitle = NULL; m->scr.frame.help = talloc_strdup(m, - _("Enter=accept, e=edit, n=new, x=exit, l=language, h=help")); + _("Enter=accept, e=edit, n=new, x=exit, l=language, g=log, h=help")); m->scr.frame.status = talloc_strdup(m, _("Welcome to Petitboot")); /* add a separator */ @@ -878,25 +900,29 @@ static struct pmenu *main_menu_init(struct cui *cui) i->on_execute = menu_config_execute; pmenu_item_insert(m, i, 2); + i = pmenu_item_create(m, _("System status log")); + i->on_execute = menu_statuslog_execute; + pmenu_item_insert(m, i, 3); + /* this label isn't translated, so we don't want a gettext() here */ i = pmenu_item_create(m, "Language"); i->on_execute = menu_lang_execute; - pmenu_item_insert(m, i, 3); + pmenu_item_insert(m, i, 4); i = pmenu_item_create(m, _("Rescan devices")); i->on_execute = menu_reinit_execute; - pmenu_item_insert(m, i, 4); + pmenu_item_insert(m, i, 5); i = pmenu_item_create(m, _("Retrieve config from URL")); i->on_execute = menu_add_url_execute; - pmenu_item_insert(m, i, 5); + pmenu_item_insert(m, i, 6); if (lockdown) i = pmenu_item_create(m, _("Reboot")); else i = pmenu_item_create(m, _("Exit to shell")); i->on_execute = pmenu_exit_cb; - pmenu_item_insert(m, i, 6); + pmenu_item_insert(m, i, 7); result = pmenu_setup(m); @@ -1023,6 +1049,7 @@ struct cui *cui_init(void* platform_info, cui->c_sig = pb_cui_sig; cui->platform_info = platform_info; cui->waitset = waitset_create(cui); + cui->statuslog = statuslog_init(cui); process_init(cui, cui->waitset, false); diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index b00d251..418df71 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -56,6 +56,7 @@ struct cui { struct waitset *waitset; struct discover_client *client; struct system_info *sysinfo; + struct statuslog *statuslog; struct sysinfo_screen *sysinfo_screen; struct config *config; struct config_screen *config_screen; @@ -64,6 +65,7 @@ struct cui { struct lang_screen *lang_screen; struct help_screen *help_screen; struct subset_screen *subset_screen; + struct statuslog_screen *statuslog_screen; struct pjs *pjs; void *platform_info; unsigned int default_item; @@ -80,6 +82,7 @@ void cui_item_new(struct pmenu *menu); void cui_show_sysinfo(struct cui *cui); void cui_show_config(struct cui *cui); void cui_show_lang(struct cui *cui); +void cui_show_statuslog(struct cui *cui); void cui_show_help(struct cui *cui, const char *title, const struct help_text *text); void cui_show_subset(struct cui *cui, const char *title, diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c index 723d348..90a2c0a 100644 --- a/ui/ncurses/nc-menu.c +++ b/ui/ncurses/nc-menu.c @@ -418,6 +418,9 @@ static void pmenu_process_key(struct nc_scr *scr, int key) case 'l': cui_show_lang(cui_from_arg(scr->ui_ctx)); break; + case 'g': + cui_show_statuslog(cui_from_arg(scr->ui_ctx)); + break; case KEY_F(1): case 'h': if (menu->help_text) diff --git a/ui/ncurses/nc-statuslog.c b/ui/ncurses/nc-statuslog.c new file mode 100644 index 0000000..1943f39 --- /dev/null +++ b/ui/ncurses/nc-statuslog.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include + +#include +#include +#include +#include +#include + +#include "nc-cui.h" +#include "nc-textscreen.h" +#include "nc-statuslog.h" + +static const int max_status_entry = 10000; + +struct statuslog_entry { + struct status *status; + struct list_item list; +}; + +struct statuslog { + struct list status; + int n_status; + bool truncated; +}; + +struct statuslog_screen { + struct text_screen text_scr; +}; + +struct statuslog *statuslog_init(struct cui *cui) +{ + struct statuslog *sl; + + sl = talloc(cui, struct statuslog); + sl->truncated = false; + sl->n_status = 0; + list_init(&sl->status); + + return sl; +} + +void statuslog_append_steal(struct cui *cui, struct statuslog *statuslog, + struct status *status) +{ + struct statuslog_entry *entry; + + entry = talloc(statuslog, struct statuslog_entry); + entry->status = status; + talloc_steal(statuslog, status); + + list_add_tail(&statuslog->status, &entry->list); + + if (statuslog->n_status >= max_status_entry) { + list_remove(&statuslog->status.head); + statuslog->truncated = true; + statuslog->n_status--; + } + + statuslog->n_status++; + + if (cui->statuslog_screen) { + text_screen_append_line(&cui->statuslog_screen->text_scr, + "%s", status->message); + text_screen_draw(&cui->statuslog_screen->text_scr); + } +} + +struct statuslog_screen *statuslog_screen_init(struct cui *cui, + void (*on_exit)(struct cui *)) +{ + struct statuslog_screen *screen; + struct statuslog_entry *entry; + const char *title; + + screen = talloc_zero(cui, struct statuslog_screen); + + title = _("Petitboot status log"); + + text_screen_init(&screen->text_scr, cui, title, on_exit); + list_for_each_entry(&cui->statuslog->status, entry, list) { + text_screen_append_line(&screen->text_scr, "%s", + entry->status->message); + } + text_screen_draw(&screen->text_scr); + + return screen; +} + +struct nc_scr *statuslog_screen_scr(struct statuslog_screen *screen) +{ + return text_screen_scr(&screen->text_scr); +} diff --git a/ui/ncurses/nc-statuslog.h b/ui/ncurses/nc-statuslog.h new file mode 100644 index 0000000..e29980e --- /dev/null +++ b/ui/ncurses/nc-statuslog.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _NC_STATUSLOG_H +#define _NC_STATUSLOG_H + +#include "nc-cui.h" + +struct statuslog; +struct statuslog_screen; + +struct statuslog *statuslog_init(struct cui *cui); +void statuslog_append_steal(struct cui *cui, struct statuslog *statuslog, + struct status *status); + +struct statuslog_screen *statuslog_screen_init(struct cui *cui, + void (*on_exit)(struct cui *)); + +struct nc_scr *statuslog_screen_scr(struct statuslog_screen *screen); + +#endif /* defined _NC_STATUSLOG_H */ -- cgit v1.2.1