]> git.ozlabs.org Git - petitboot/commitdiff
ui/ncurses: Add support for 'add-url' action
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Thu, 24 Jul 2014 05:05:39 +0000 (15:05 +1000)
committerJeremy Kerr <jk@ozlabs.org>
Mon, 28 Jul 2014 08:12:13 +0000 (16:12 +0800)
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>
po/POTFILES.in
po/en.po
ui/common/discover-client.c
ui/common/discover-client.h
ui/ncurses/Makefile.am
ui/ncurses/nc-add-url-help.c [new file with mode: 0644]
ui/ncurses/nc-add-url.c [new file with mode: 0644]
ui/ncurses/nc-add-url.h [new file with mode: 0644]
ui/ncurses/nc-cui.c
ui/ncurses/nc-cui.h
ui/ncurses/nc-scr.h

index ab96d5af0a08521c5479fc5eb72e08b97422b96b..07ed13543a3a6f0d55388e1c4d81b3526d563c31 100644 (file)
@@ -2,6 +2,7 @@
 
 discover/boot.c
 discover/device-handler.c
+ui/ncurses/nc-add-url.c
 ui/ncurses/nc-boot-editor.c
 ui/ncurses/nc-config.c
 ui/ncurses/nc-cui.c
@@ -11,6 +12,7 @@ ui/ncurses/nc-menu.c
 ui/ncurses/nc-sysinfo.c
 ui/ncurses/nc-textscreen.c
 ui/ncurses/nc-cui-help.c
+ui/ncurses/nc-add-url-help.c
 ui/ncurses/nc-boot-editor-help.c
 ui/ncurses/nc-config-help.c
 ui/ncurses/nc-sysinfo-help.c
index 3355e9978e49ca2ab4f2c46a9f150eb80d1f1f0e..52a4c3ffb1bc69f9c60bac110d1426a606344978 100644 (file)
--- a/po/en.po
+++ b/po/en.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: petitboot 20140623-g89bd2ed2-dirty\n"
 "Report-Msgid-Bugs-To: Geoff Levand <geoff@infradead.org>\n"
-"POT-Creation-Date: 2014-07-28 13:48+0800\n"
+"POT-Creation-Date: 2014-07-28 16:06+0800\n"
 "PO-Revision-Date: 2014-06-24 13:56+0800\n"
 "Last-Translator: Jeremy Kerr <jk@ozlabs.org>\n"
 "Language-Team: English\n"
@@ -59,6 +59,42 @@ msgstr "Booting in %d sec: %s"
 msgid "Default boot cancelled"
 msgstr "Default boot cancelled"
 
+#, c-format
+msgid "Received config URL %s"
+msgstr "Received config URL %s"
+
+msgid "Invalid config URL!"
+msgstr "Invalid config URL!"
+
+#, c-format
+msgid "Unable to route to host %s"
+msgstr "Unable to route to host %s"
+
+#, c-format
+msgid "Config file %s parsed"
+msgstr "Config file %s parsed"
+
+msgid "Retrieve Config"
+msgstr "Retrieve Config"
+
+msgid "Configuration URL:"
+msgstr "Configuration URL:"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Help"
+msgstr "Help"
+
+msgid "Cancel"
+msgstr "Cancel"
+
+msgid "Petitboot Config Retrieval"
+msgstr "Petitboot Config Retrieval"
+
+msgid "tab=next, shift+tab=previous, x=exit, h=help"
+msgstr "tab=next, shift+tab=previous, x=exit, h=help"
+
 msgid "Boot Option Editor"
 msgstr "Boot Option Editor"
 
@@ -80,21 +116,9 @@ msgstr "Device tree:"
 msgid "Boot arguments:"
 msgstr "Boot arguments:"
 
-msgid "OK"
-msgstr "OK"
-
-msgid "Help"
-msgstr "Help"
-
-msgid "Cancel"
-msgstr "Cancel"
-
 msgid "Petitboot Option Editor"
 msgstr "Petitboot Option Editor"
 
-msgid "tab=next, shift+tab=previous, x=exit, h=help"
-msgstr "tab=next, shift+tab=previous, x=exit, h=help"
-
 msgid "System Configuration"
 msgstr "System Configuration"
 
@@ -221,6 +245,9 @@ msgstr "System information"
 msgid "System configuration"
 msgstr "System configuration"
 
+msgid "Retrieve config from URL"
+msgstr "Retrieve config from URL"
+
 msgid "Exit to shell"
 msgstr "Exit to shell"
 
@@ -337,6 +364,19 @@ msgstr ""
 "\n"
 "To close the Petitboot interface, type X (exit).\n"
 
+msgid ""
+"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"
+msgstr ""
+"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"
+
 msgid ""
 "This screen allows you to edit or create boot options.\n"
 "\n"
index a565be880f272293eb0b372c72bf84a04b218f32..14f36da4e9004871f7704e8f76dcaea2a3fe253b 100644 (file)
@@ -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);
+}
index d5c573f22de0bdfed18c8d7387514c52bc252b00..542a275bbc6230095cd93c1122125f2ae7dca085 100644 (file)
@@ -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
index 06f272f5624faed7bf3587089217974a1662dd03..6112b655c206cfff595f3bbaa099a9f18b65e919 100644 (file)
@@ -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 (file)
index 0000000..cc78fd0
--- /dev/null
@@ -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 (file)
index 0000000..b1a31dd
--- /dev/null
@@ -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 (file)
index 0000000..319dd42
--- /dev/null
@@ -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 */
index 4f03409fac2ed81723ca7e3dcdd607f6f30a0a78..3f1e0a265176c0377315448d6398a074ea6ae88f 100644 (file)
@@ -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);
 
index ff735ae444be2ee37724c83ae31ec67998a58c64..694ebd1fbaceaa9a291dc7e6834620a2ccb55560 100644 (file)
@@ -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 */
index 3d7c4ebcd919207c12b8607d3fd0e478fe2e636c..ed87517cb292c1f85c66571a302a228adc6f0d8e 100644 (file)
@@ -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)