diff options
author | Samuel Mendoza-Jonas <sam.mj@au1.ibm.com> | 2014-07-24 15:05:39 +1000 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2014-07-28 16:12:13 +0800 |
commit | 254c2c4233377ba71d0f1c96a77d885c91f9ad4a (patch) | |
tree | f6e79dbeba93f7709be8a9a261dd101be73bbd03 /ui | |
parent | 0f5d4481891467000c50bf14548c236cfb3e70ad (diff) | |
download | talos-petitboot-254c2c4233377ba71d0f1c96a77d885c91f9ad4a.tar.gz talos-petitboot-254c2c4233377ba71d0f1c96a77d885c91f9ad4a.zip |
ui/ncurses: Add support for 'add-url' action
Creates a menu option to specify a remote conf file url to send to
the server for parsing.
Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'ui')
-rw-r--r-- | ui/common/discover-client.c | 18 | ||||
-rw-r--r-- | ui/common/discover-client.h | 4 | ||||
-rw-r--r-- | ui/ncurses/Makefile.am | 5 | ||||
-rw-r--r-- | ui/ncurses/nc-add-url-help.c | 8 | ||||
-rw-r--r-- | ui/ncurses/nc-add-url.c | 248 | ||||
-rw-r--r-- | ui/ncurses/nc-add-url.h | 31 | ||||
-rw-r--r-- | ui/ncurses/nc-cui.c | 33 | ||||
-rw-r--r-- | ui/ncurses/nc-cui.h | 3 | ||||
-rw-r--r-- | ui/ncurses/nc-scr.h | 3 |
9 files changed, 349 insertions, 4 deletions
diff --git a/ui/common/discover-client.c b/ui/common/discover-client.c index a565be8..14f36da 100644 --- a/ui/common/discover-client.c +++ b/ui/common/discover-client.c @@ -383,3 +383,21 @@ int discover_client_send_config(struct discover_client *client, return pb_protocol_write_message(client->fd, message); } + +int discover_client_send_url(struct discover_client *client, + char *url) +{ + struct pb_protocol_message *message; + int len; + + len = pb_protocol_url_len(url); + + message = pb_protocol_create_message(client, + PB_PROTOCOL_ACTION_ADD_URL, len); + if (!message) + return -1; + + pb_protocol_serialise_url(url, message->payload, len); + + return pb_protocol_write_message(client->fd, message); +} diff --git a/ui/common/discover-client.h b/ui/common/discover-client.h index d5c573f..542a275 100644 --- a/ui/common/discover-client.h +++ b/ui/common/discover-client.h @@ -87,4 +87,8 @@ int discover_client_send_config(struct discover_client *client, * and ops->boot_option_add on each. */ void discover_client_enumerate(struct discover_client *client); + +/* Send url to config to the discover server */ +int discover_client_send_url(struct discover_client *client, char *url); + #endif diff --git a/ui/ncurses/Makefile.am b/ui/ncurses/Makefile.am index 06f272f..6112b65 100644 --- a/ui/ncurses/Makefile.am +++ b/ui/ncurses/Makefile.am @@ -53,7 +53,10 @@ libpbnc_la_SOURCES = \ nc-textscreen.c \ nc-textscreen.h \ nc-widgets.c \ - nc-widgets.h + nc-widgets.h \ + nc-add-url.c \ + nc-add-url.h \ + nc-add-url-help.c sbin_PROGRAMS = petitboot-nc diff --git a/ui/ncurses/nc-add-url-help.c b/ui/ncurses/nc-add-url-help.c new file mode 100644 index 0000000..cc78fd0 --- /dev/null +++ b/ui/ncurses/nc-add-url-help.c @@ -0,0 +1,8 @@ +#include "nc-helpscreen.h" + +struct help_text add_url_help_text = define_help_text("\ +Supply a valid URL here to retrieve a remote boot config file, \ +(eg: petitboot.conf) and parse it.\n\ +\n\ +URLs are of the form 'scheme://host/path/to/petitboot.conf', \ +such as tftp://host/petitboot.conf or http://host/petitboot.conf"); diff --git a/ui/ncurses/nc-add-url.c b/ui/ncurses/nc-add-url.c new file mode 100644 index 0000000..b1a31dd --- /dev/null +++ b/ui/ncurses/nc-add-url.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2013 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 <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <talloc/talloc.h> +#include <types/types.h> +#include <i18n/i18n.h> +#include <log/log.h> + +#include "nc-cui.h" +#include "nc-add-url.h" +#include "nc-widgets.h" + +#define N_FIELDS 5 + +extern const struct help_text add_url_help_text; + +struct add_url_screen { + struct nc_scr scr; + struct cui *cui; + struct nc_widgetset *widgetset; + + bool exit; + bool show_help; + void (*on_exit)(struct cui *); + + int label_x; + int field_x; + + struct { + struct nc_widget_textbox *url_f; + struct nc_widget_label *url_l; + + struct nc_widget_button *ok_b; + struct nc_widget_button *help_b; + struct nc_widget_button *cancel_b; + } widgets; +}; + +static struct add_url_screen *add_url_screen_from_scr(struct nc_scr *scr) +{ + struct add_url_screen *add_url_screen; + + assert(scr->sig == pb_add_url_screen_sig); + add_url_screen = (struct add_url_screen *) + ((char *)scr - (size_t)&((struct add_url_screen *)0)->scr); + assert(add_url_screen->scr.sig == pb_add_url_screen_sig); + return add_url_screen; +} + +static void add_url_screen_process_key(struct nc_scr *scr, int key) +{ + struct add_url_screen *screen = add_url_screen_from_scr(scr); + bool handled; + + handled = widgetset_process_key(screen->widgetset, key); + + if (!handled) { + switch (key) { + case 'x': + case 27: /* esc */ + screen->exit = true; + break; + case 'h': + screen->show_help = true; + break; + } + } + + if (screen->exit) { + screen->on_exit(screen->cui); + + } else if (screen->show_help) { + screen->show_help = false; + cui_show_help(screen->cui, _("Retrieve Config"), + &add_url_help_text); + + } else if (handled) { + wrefresh(screen->scr.main_ncw); + } +} + +static int add_url_screen_post(struct nc_scr *scr) +{ + struct add_url_screen *screen = add_url_screen_from_scr(scr); + widgetset_post(screen->widgetset); + nc_scr_frame_draw(scr); + redrawwin(scr->main_ncw); + wrefresh(screen->scr.main_ncw); + return 0; +} + +static int add_url_screen_unpost(struct nc_scr *scr) +{ + struct add_url_screen *screen = add_url_screen_from_scr(scr); + widgetset_unpost(screen->widgetset); + return 0; +} + +struct nc_scr *add_url_screen_scr(struct add_url_screen *screen) +{ + return &screen->scr; +} + +static int screen_process_form(struct add_url_screen *screen) +{ + char *url; + int rc; + + url = widget_textbox_get_value(screen->widgets.url_f); + if (!url || !strlen(url)) + return 0; + + /* Once we have all the info we need, tell the server */ + rc = cui_send_url(screen->cui, url); + + if (rc) + pb_log("cui_send_retreive failed!\n"); + else + pb_debug("add_url url sent!\n"); + return 0; +} + +static void ok_click(void *arg) +{ + struct add_url_screen *screen = arg; + if (screen_process_form(screen)) + /* errors are written to the status line, so we'll need + * to refresh */ + wrefresh(screen->scr.main_ncw); + else + screen->exit = true; +} + +static void help_click(void *arg) +{ + struct add_url_screen *screen = arg; + screen->show_help = true; +} + +static void cancel_click(void *arg) +{ + struct add_url_screen *screen = arg; + screen->exit = true; +} + +static int layout_pair(struct add_url_screen *screen, int y, + struct nc_widget_label *label, + struct nc_widget *field) +{ + struct nc_widget *label_w = widget_label_base(label); + widget_move(label_w, y, screen->label_x); + widget_move(field, y, screen->field_x); + return max(widget_height(label_w), widget_height(field)); +} + +static void add_url_screen_layout_widgets(struct add_url_screen *screen) +{ + int y = 2; + + /* url field */ + y += layout_pair(screen, y, screen->widgets.url_l, + widget_textbox_base(screen->widgets.url_f)); + + /* ok, help, cancel */ + y += 1; + + widget_move(widget_button_base(screen->widgets.ok_b), + y, screen->field_x); + widget_move(widget_button_base(screen->widgets.help_b), + y, screen->field_x + 10); + widget_move(widget_button_base(screen->widgets.cancel_b), + y, screen->field_x + 20); +} + +static void add_url_screen_setup_widgets(struct add_url_screen *screen) +{ + struct nc_widgetset *set = screen->widgetset; + + build_assert(sizeof(screen->widgets) / sizeof(struct widget *) + == N_FIELDS); + + screen->widgets.url_l = widget_new_label(set, 0, 0, + _("Configuration URL:")); + screen->widgets.url_f = widget_new_textbox(set, 0, 0, 50, NULL); + + screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"), + ok_click, screen); + screen->widgets.help_b = widget_new_button(set, 0, 0, 6, _("Help"), + help_click, screen); + screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, _("Cancel"), + cancel_click, screen); +} + +struct add_url_screen *add_url_screen_init(struct cui *cui, + void (*on_exit)(struct cui *)) +{ + struct add_url_screen *screen; + + screen = talloc_zero(cui, struct add_url_screen); + + screen->cui = cui; + screen->on_exit = on_exit; + screen->label_x = 2; + screen->field_x = 22; + + nc_scr_init(&screen->scr, pb_add_url_screen_sig, 0, + cui, add_url_screen_process_key, + add_url_screen_post, add_url_screen_unpost, + NULL); + + screen->scr.frame.ltitle = talloc_strdup(screen, + _("Petitboot Config Retrieval")); + screen->scr.frame.rtitle = NULL; + screen->scr.frame.help = talloc_strdup(screen, + _("tab=next, shift+tab=previous, x=exit, h=help")); + nc_scr_frame_draw(&screen->scr); + + screen->widgetset = widgetset_create(screen, screen->scr.main_ncw, + NULL); + + add_url_screen_setup_widgets(screen); + add_url_screen_layout_widgets(screen); + + return screen; +} + diff --git a/ui/ncurses/nc-add-url.h b/ui/ncurses/nc-add-url.h new file mode 100644 index 0000000..319dd42 --- /dev/null +++ b/ui/ncurses/nc-add-url.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 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_ADD_URL_H +#define _NC_ADD_URL_H + +#include "nc-cui.h" + +struct add_url_screen; + +struct add_url_screen *add_url_screen_init(struct cui *cui, + void (*on_exit)(struct cui *)); + +struct nc_scr *add_url_screen_scr(struct add_url_screen *screen); +void add_url_screen_update(struct add_url_screen *screen); + +#endif /* defined _NC_ADD_URL_H */ diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 4f03409..3f1e0a2 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -37,6 +37,7 @@ #include "nc-cui.h" #include "nc-boot-editor.h" #include "nc-config.h" +#include "nc-add-url.h" #include "nc-sysinfo.h" #include "nc-lang.h" #include "nc-helpscreen.h" @@ -281,6 +282,19 @@ void cui_show_lang(struct cui *cui) cui_set_current(cui, lang_screen_scr(cui->lang_screen)); } +static void cui_add_url_exit(struct cui *cui) +{ + cui_set_current(cui, &cui->main->scr); + talloc_free(cui->add_url_screen); + cui->add_url_screen = NULL; +} + +void cui_show_add_url(struct cui *cui) +{ + cui->add_url_screen = add_url_screen_init(cui, cui_add_url_exit); + cui_set_current(cui, add_url_screen_scr(cui->add_url_screen)); +} + static void cui_help_exit(struct cui *cui) { cui_set_current(cui, help_screen_return_scr(cui->help_screen)); @@ -684,6 +698,11 @@ int cui_send_config(struct cui *cui, struct config *config) return discover_client_send_config(cui->client, config); } +int cui_send_url(struct cui *cui, char * url) +{ + return discover_client_send_url(cui->client, url); +} + void cui_send_reinit(struct cui *cui) { discover_client_send_reinit(cui->client); @@ -713,6 +732,12 @@ static int menu_reinit_execute(struct pmenu_item *item) return 0; } +static int menu_add_url_execute(struct pmenu_item *item) +{ + cui_show_add_url(cui_from_item(item)); + return 0; +} + /** * pb_mm_init - Setup the main menu instance. */ @@ -722,7 +747,7 @@ static struct pmenu *main_menu_init(struct cui *cui) struct pmenu *m; int result; - m = pmenu_init(cui, 6, cui_on_exit); + m = pmenu_init(cui, 7, cui_on_exit); if (!m) { pb_log("%s: failed\n", __func__); return NULL; @@ -760,9 +785,13 @@ static struct pmenu *main_menu_init(struct cui *cui) i->on_execute = menu_reinit_execute; pmenu_item_insert(m, i, 4); + i = pmenu_item_create(m, _("Retrieve config from URL")); + i->on_execute = menu_add_url_execute; + pmenu_item_insert(m, i, 5); + i = pmenu_item_create(m, _("Exit to shell")); i->on_execute = pmenu_exit_cb; - pmenu_item_insert(m, i, 5); + pmenu_item_insert(m, i, 6); result = pmenu_setup(m); diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index ff735ae..694ebd1 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -59,6 +59,7 @@ struct cui { struct sysinfo_screen *sysinfo_screen; struct config *config; struct config_screen *config_screen; + struct add_url_screen *add_url_screen; struct boot_editor *boot_editor; struct lang_screen *lang_screen; struct help_screen *help_screen; @@ -80,7 +81,9 @@ void cui_show_config(struct cui *cui); void cui_show_lang(struct cui *cui); void cui_show_help(struct cui *cui, const char *title, const struct help_text *text); +void cui_show_add_url(struct cui *cui); int cui_send_config(struct cui *cui, struct config *config); +int cui_send_url(struct cui *cui, char *url); void cui_send_reinit(struct cui *cui); /* convenience routines */ diff --git a/ui/ncurses/nc-scr.h b/ui/ncurses/nc-scr.h index 3d7c4eb..ed87517 100644 --- a/ui/ncurses/nc-scr.h +++ b/ui/ncurses/nc-scr.h @@ -47,7 +47,8 @@ enum pb_nc_sig { pb_text_screen_sig = 555, pb_config_screen_sig = 666, pb_lang_screen_sig = 777, - pb_removed_sig = -888, + pb_add_url_screen_sig = 888, + pb_removed_sig = -999, }; static inline void nc_flush_keys(void) |