X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=ui%2Fncurses%2Fnc-config.c;h=943ee8a87daeb3012da04b0e36cd64991e99fabb;hp=c0df762f155a236f0736fb577e09f99c7fa9a1e8;hb=9e869ebe3a5127575105d82c4d289d95cbed2db9;hpb=aae41a6e324cb37c7af93ae8726110ff82728fa6 diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c index c0df762..943ee8a 100644 --- a/ui/ncurses/nc-config.c +++ b/ui/ncurses/nc-config.c @@ -29,11 +29,12 @@ #include #include +#include "ui/common/discover-client.h" #include "nc-cui.h" #include "nc-config.h" #include "nc-widgets.h" -#define N_FIELDS 39 +#define N_FIELDS 51 extern struct help_text config_help_text; @@ -51,7 +52,6 @@ struct config_screen { bool exit; bool show_help; - bool show_subset; bool need_redraw; bool need_update; @@ -67,6 +67,8 @@ struct config_screen { bool autoboot_enabled; bool ipmi_override; + bool ipmi_mailbox; + bool net_override; struct { struct nc_widget_label *autoboot_l; @@ -83,7 +85,10 @@ struct config_screen { struct nc_widget_label *ipmi_type_l; struct nc_widget_label *ipmi_clear_l; - struct nc_widget_checkbox *ipmi_clear_cb; + struct nc_widget_button *ipmi_clear_b; + + struct nc_widget_label *ipmi_mailbox_l; + struct nc_widget_button *ipmi_mailbox_b; struct nc_widget_label *network_l; struct nc_widget_select *network_f; @@ -105,10 +110,21 @@ struct config_screen { struct nc_widget_textbox *dns_f; struct nc_widget_label *dns_dhcp_help_l; struct nc_widget_label *dns_help_l; + struct nc_widget_label *http_proxy_l; + struct nc_widget_textbox *http_proxy_f; + struct nc_widget_label *https_proxy_l; + struct nc_widget_textbox *https_proxy_f; struct nc_widget_label *allow_write_l; struct nc_widget_select *allow_write_f; + struct nc_widget_label *boot_console_l; + struct nc_widget_select *boot_console_f; + struct nc_widget_label *manual_console_l; + struct nc_widget_label *current_console_l; + + struct nc_widget_button *update_password_l; + struct nc_widget_label *net_override_l; struct nc_widget_label *safe_mode; struct nc_widget_button *ok_b; struct nc_widget_button *help_b; @@ -165,7 +181,7 @@ static void config_screen_process_key(struct nc_scr *scr, int key) cui_show_help(screen->cui, _("System Configuration"), &config_help_text); - } else if (handled && !screen->show_subset) { + } else if (handled && (screen->cui->current == scr)) { pad_refresh(screen); } } @@ -193,11 +209,11 @@ static int screen_process_form(struct config_screen *screen) const struct system_info *sysinfo = screen->cui->sysinfo; enum net_conf_type net_conf_type; struct interface_config *iface; - bool allow_write, autoboot; + bool allow_write; char *str, *end; struct config *config; - int i, n_boot_opts, rc, idx; - unsigned int *order; + int i, n_boot_opts, rc; + unsigned int *order, idx; char mac[20]; config = config_copy(screen, screen->cui->config); @@ -208,8 +224,8 @@ static int screen_process_form(struct config_screen *screen) n_boot_opts = widget_subset_get_order(config, &order, screen->widgets.boot_order_f); - autoboot = widget_select_get_value(screen->widgets.autoboot_f); - config->autoboot_enabled = autoboot || (autoboot && n_boot_opts); + config->autoboot_enabled = widget_select_get_value( + screen->widgets.autoboot_f); config->n_autoboot_opts = n_boot_opts; config->autoboot_opts = talloc_array(config, struct autoboot_option, @@ -246,11 +262,6 @@ static int screen_process_form(struct config_screen *screen) config->autoboot_timeout_sec = x; } - if (screen->ipmi_override) - if (widget_checkbox_get_value(screen->widgets.ipmi_clear_cb)) - config->ipmi_bootdev = IPMI_BOOTDEV_INVALID; - - net_conf_type = widget_select_get_value(screen->widgets.network_f); /* if we don't have any network interfaces, prevent per-interface @@ -329,10 +340,30 @@ static int screen_process_form(struct config_screen *screen) } } + talloc_free(config->http_proxy); + talloc_free(config->https_proxy); + str = widget_textbox_get_value(screen->widgets.http_proxy_f); + config->http_proxy = talloc_strdup(config, str); + str = widget_textbox_get_value(screen->widgets.https_proxy_f); + config->https_proxy = talloc_strdup(config, str); + allow_write = widget_select_get_value(screen->widgets.allow_write_f); if (allow_write != config->allow_writes) config->allow_writes = allow_write; + if (config->n_consoles && !config->manual_console) { + idx = widget_select_get_value(screen->widgets.boot_console_f); + if (!config->boot_console) { + config->boot_console = talloc_strdup(config, + config->consoles[idx]); + } else if (strncmp(config->boot_console, config->consoles[idx], + strlen(config->boot_console)) != 0) { + talloc_free(config->boot_console); + config->boot_console = talloc_strdup(config, + config->consoles[idx]); + } + } + config->safe_mode = false; rc = cui_send_config(screen->cui, config); talloc_free(config); @@ -345,15 +376,39 @@ static int screen_process_form(struct config_screen *screen) return 0; } +static void config_screen_config_cb(struct nc_scr *scr) +{ + struct config_screen *screen = config_screen_from_scr(scr); + + if (!screen_process_form(screen)) + screen->exit = true; +} + +#ifdef CRYPT_SUPPORT +static void password_click(void *arg) +{ + struct config_screen *screen = arg; + + screen->need_update = true; + cui_show_auth(screen->cui, screen->scr.main_ncw, true, NULL); +} +#endif + static void ok_click(void *arg) { struct config_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; + + if (discover_client_authenticated(screen->cui->client)) { + 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; + } else { + cui_show_auth(screen->cui, screen->scr.main_ncw, false, + config_screen_config_cb); + } } static void help_click(void *arg) @@ -368,6 +423,47 @@ static void cancel_click(void *arg) screen->exit = true; } +static void ipmi_clear_click(void *arg) +{ + struct config_screen *screen = arg; + struct config *config; + int rc; + + config = config_copy(screen, screen->cui->config); + config->ipmi_bootdev = IPMI_BOOTDEV_INVALID; + config->safe_mode = false; + + rc = cui_send_config(screen->cui, config); + talloc_free(config); + + if (rc) + pb_log("cui_send_config failed!\n"); + else + pb_debug("config sent!\n"); + screen->exit = true; +} + +static void ipmi_clear_mailbox_click(void *arg) +{ + struct config_screen *screen = arg; + struct config *config; + int rc; + + config = config_copy(screen, screen->cui->config); + config->ipmi_bootdev_mailbox = false; + config->safe_mode = false; + + rc = cui_send_config(screen->cui, config); + talloc_free(config); + + if (rc) + pb_log("cui_send_config failed!\n"); + else + pb_debug("config sent!\n"); + screen->exit = true; +} + + static int layout_pair(struct config_screen *screen, int y, struct nc_widget_label *label, struct nc_widget *field) @@ -395,6 +491,7 @@ static void config_screen_layout_widgets(struct config_screen *screen) widget_move(wl, y, screen->label_x); wf = widget_select_base(screen->widgets.autoboot_f); + widget_set_visible(wf, true); widget_move(wf, y, screen->field_x); y += widget_height(wf); @@ -456,7 +553,8 @@ static void config_screen_layout_widgets(struct config_screen *screen) widget_move(wf, y, screen->field_x); widget_move(wh, y, screen->field_x + widget_width(wf) + 1); y += 2; - } + } else + y += 1; if (screen->ipmi_override) { wl = widget_label_base(screen->widgets.ipmi_type_l); @@ -465,7 +563,7 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; wl = widget_label_base(screen->widgets.ipmi_clear_l); - wf = widget_checkbox_base(screen->widgets.ipmi_clear_cb); + wf = widget_button_base(screen->widgets.ipmi_clear_b); widget_set_visible(wl, true); widget_set_visible(wf, true); widget_move(wl, y, screen->label_x); @@ -473,6 +571,18 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; } + if (screen->ipmi_mailbox) { + wl = widget_label_base(screen->widgets.ipmi_mailbox_l); + widget_set_visible(wl, true); + widget_move(wl, y, screen->label_x); + y += 1; + + wf = widget_button_base(screen->widgets.ipmi_mailbox_b); + widget_set_visible(wf, true); + widget_move(wf, y, screen->field_x); + y += 1; + } + y += 1; y += layout_pair(screen, y, screen->widgets.network_l, @@ -564,14 +674,14 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; } - y += 1; + wf = widget_textbox_base(screen->widgets.http_proxy_f); + layout_pair(screen, y, screen->widgets.http_proxy_l, wf); + y++; + wf = widget_textbox_base(screen->widgets.https_proxy_f); + layout_pair(screen, y, screen->widgets.https_proxy_l, wf); + y++; - show = screen->cui->config->safe_mode; - if (show) { - widget_move(widget_label_base(screen->widgets.safe_mode), - y, screen->field_x); - y += 1; - } + y += 1; layout_pair(screen, y, screen->widgets.allow_write_l, widget_select_base(screen->widgets.allow_write_f)); @@ -579,6 +689,52 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; + if (screen->widgets.manual_console_l) { + layout_pair(screen, y++, screen->widgets.boot_console_l, + widget_label_base(screen->widgets.manual_console_l)); + widget_move(widget_label_base(screen->widgets.current_console_l), + y, screen->field_x); + widget_set_visible(widget_select_base( + screen->widgets.boot_console_f), false); + y += 2; + } else if (widget_height(widget_select_base(screen->widgets.boot_console_f))) { + layout_pair(screen, y, screen->widgets.boot_console_l, + widget_select_base(screen->widgets.boot_console_f)); + y += widget_height(widget_select_base(screen->widgets.boot_console_f)); + widget_move(widget_label_base(screen->widgets.current_console_l), + y, screen->field_x); + y += 2; + } else { + widget_set_visible(widget_label_base( + screen->widgets.boot_console_l), false); + widget_set_visible(widget_select_base( + screen->widgets.boot_console_f), false); + widget_set_visible(widget_label_base( + screen->widgets.current_console_l), false); + } + +#ifdef CRYPT_SUPPORT + widget_move(widget_button_base(screen->widgets.update_password_l), + y, screen->field_x); + y += 2; +#endif + + if (screen->net_override) { + widget_move(widget_label_base(screen->widgets.net_override_l), + y, screen->label_x); + widget_set_visible(widget_label_base(screen->widgets.net_override_l), + true); + y += 1; + } + + if (screen->cui->config->safe_mode) { + widget_move(widget_label_base(screen->widgets.safe_mode), + y, screen->label_x); + widget_set_visible(widget_label_base(screen->widgets.safe_mode), + true); + y += 1; + } + widget_move(widget_button_base(screen->widgets.ok_b), y, screen->field_x); widget_move(widget_button_base(screen->widgets.help_b), @@ -618,7 +774,6 @@ static void config_screen_add_device(void *arg) { struct config_screen *screen = arg; - screen->show_subset = true; cui_show_subset(screen->cui, _("Select a boot device to add"), screen->widgets.boot_order_f); } @@ -629,7 +784,6 @@ static void config_screen_autoboot_none(void *arg) struct nc_widget_subset *subset = screen->widgets.boot_order_f; widget_subset_clear_active(subset); - screen->autoboot_enabled = false; widgetset_unpost(screen->widgetset); config_screen_layout_widgets(screen); @@ -741,10 +895,11 @@ static void config_screen_setup_widgets(struct config_screen *screen, { struct nc_widgetset *set = screen->widgetset; struct interface_config *ifcfg; - char *str, *ip, *mask, *gw, *url; + char *str, *ip, *mask, *gw, *url, *tty, *label; enum net_conf_type type; unsigned int i; int add_len, clear_len, any_len, min_len = 20; + bool found; build_assert(sizeof(screen->widgets) / sizeof(struct widget *) == N_FIELDS); @@ -796,7 +951,6 @@ static void config_screen_setup_widgets(struct config_screen *screen, for (i = 0; i < sysinfo->n_blockdevs; i++) { struct blockdev_info *bd = sysinfo->blockdevs[i]; - char *label; label = talloc_asprintf(screen, _("disk: %s [uuid: %s]"), bd->name, bd->uuid); @@ -806,7 +960,7 @@ static void config_screen_setup_widgets(struct config_screen *screen, for (i = 0; i < sysinfo->n_interfaces; i++) { struct interface_info *info = sysinfo->interfaces[i]; - char *label, mac[20]; + char mac[20]; mac_str(info->hwaddr, info->hwaddr_size, mac, sizeof(mac)); @@ -817,7 +971,6 @@ static void config_screen_setup_widgets(struct config_screen *screen, } for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_UNKNOWN; i++) { - char *label; if (i == DEVICE_TYPE_ANY) label = talloc_asprintf(screen, _("Any Device")); @@ -858,20 +1011,32 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_textbox_set_validator_integer(screen->widgets.timeout_f, 0, 999); if (config->ipmi_bootdev) { - char *label = talloc_asprintf(screen, + label = talloc_asprintf(screen, _("%s IPMI boot option: %s"), config->ipmi_bootdev_persistent ? - "Persistent" : "Temporary", + _("Persistent") : _("Temporary"), ipmi_bootdev_display_name(config->ipmi_bootdev)); screen->widgets.ipmi_type_l = widget_new_label(set, 0, 0, label); screen->widgets.ipmi_clear_l = widget_new_label(set, 0, 0, _("Clear option:")); - screen->widgets.ipmi_clear_cb = widget_new_checkbox(set, 0, 0, - false); + screen->widgets.ipmi_clear_b = widget_new_button(set, 0, 0, + strncols(_("Clear IPMI override now")) + 10, + _("Clear IPMI override now"), + ipmi_clear_click, screen); screen->ipmi_override = true; } + if (config->ipmi_bootdev_mailbox) { + screen->widgets.ipmi_mailbox_l = widget_new_label(set, 0, 0, + _("IPMI boot order mailbox config present")); + screen->widgets.ipmi_mailbox_b = widget_new_button(set, 0, 0, + strncols(_("Clear IPMI boot order mailbox now")) + 10, + _("Clear IPMI boot order mailbox now"), + ipmi_clear_mailbox_click, screen); + screen->ipmi_mailbox = true; + } + screen->widgets.network_l = widget_new_label(set, 0, 0, _("Network:")); screen->widgets.network_f = widget_new_select(set, 0, 0, COLS - screen->field_x - 1); @@ -927,6 +1092,12 @@ static void config_screen_setup_widgets(struct config_screen *screen, url = ifcfg->static_config.url; } + screen->net_override = ifcfg && ifcfg->override; + if (screen->net_override) { + screen->widgets.net_override_l = widget_new_label(set, 0, 0, + _("Network Override Active! 'OK' will overwrite interface config")); + } + screen->widgets.ip_addr_l = widget_new_label(set, 0, 0, _("IP/mask:")); screen->widgets.ip_addr_f = widget_new_textbox(set, 0, 0, 16, ip); screen->widgets.ip_mask_l = widget_new_label(set, 0, 0, "/"); @@ -936,8 +1107,8 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_textbox_set_fixed_size(screen->widgets.ip_addr_f); widget_textbox_set_fixed_size(screen->widgets.ip_mask_f); - widget_textbox_set_validator_ipv4(screen->widgets.ip_addr_f); - widget_textbox_set_validator_integer(screen->widgets.ip_mask_f, 1, 31); + widget_textbox_set_validator_ip(screen->widgets.ip_addr_f); + widget_textbox_set_validator_integer(screen->widgets.ip_mask_f, 1, 127); screen->widgets.gateway_l = widget_new_label(set, 0, 0, _("Gateway:")); screen->widgets.gateway_f = widget_new_textbox(set, 0, 0, 16, gw); @@ -945,10 +1116,11 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_new_label(set, 0, 0, _("(eg. 192.168.0.1)")); widget_textbox_set_fixed_size(screen->widgets.gateway_f); - widget_textbox_set_validator_ipv4(screen->widgets.gateway_f); + widget_textbox_set_validator_ip(screen->widgets.gateway_f); screen->widgets.url_l = widget_new_label(set, 0, 0, _("URL:")); screen->widgets.url_f = widget_new_textbox(set, 0, 0, 32, url); + widget_textbox_set_validator_url(screen->widgets.url_f); screen->widgets.url_help_l = widget_new_label(set, 0, 0, _("(eg. tftp://)")); @@ -965,11 +1137,20 @@ static void config_screen_setup_widgets(struct config_screen *screen, screen->widgets.dns_help_l = widget_new_label(set, 0, 0, _("(eg. 192.168.0.2)")); - widget_textbox_set_validator_ipv4_multi(screen->widgets.dns_f); + widget_textbox_set_validator_ip_multi(screen->widgets.dns_f); screen->widgets.dns_dhcp_help_l = widget_new_label(set, 0, 0, _("(if not provided by DHCP server)")); + screen->widgets.http_proxy_l = widget_new_label(set, 0, 0, + _("HTTP Proxy:")); + screen->widgets.http_proxy_f = widget_new_textbox(set, 0, 0, 32, + config->http_proxy); + screen->widgets.https_proxy_l = widget_new_label(set, 0, 0, + _("HTTPS Proxy:")); + screen->widgets.https_proxy_f = widget_new_textbox(set, 0, 0, 32, + config->https_proxy); + if (config->safe_mode) screen->widgets.safe_mode = widget_new_label(set, 0, 0, _("Selecting 'OK' will exit safe mode")); @@ -987,6 +1168,34 @@ static void config_screen_setup_widgets(struct config_screen *screen, _("Allow bootloader scripts to modify disks"), config->allow_writes); + screen->widgets.boot_console_l = widget_new_label(set, 0, 0, + _("Boot console:")); + screen->widgets.boot_console_f = widget_new_select(set, 0, 0, + COLS - screen->field_x - 1); + + for (i = 0; i < config->n_consoles; i++){ + found = config->boot_console && + strncmp(config->boot_console, config->consoles[i], + strlen(config->boot_console)) == 0; + widget_select_add_option(screen->widgets.boot_console_f, i, + config->consoles[i], found); + } + + if (config->manual_console) { + label = talloc_asprintf(screen, _("Manually set: '%s'"), + config->boot_console); + screen->widgets.manual_console_l = widget_new_label(set, 0, 0, label); + } + + tty = talloc_asprintf(screen, _("Current interface: %s"), + ttyname(STDIN_FILENO)); + screen->widgets.current_console_l = widget_new_label(set, 0 , 0, tty); + +#ifdef CRYPT_SUPPORT + screen->widgets.update_password_l = widget_new_button(set, 0, 0, 30, + _("Update system password"), password_click, screen); +#endif + screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"), ok_click, screen); screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"), @@ -1086,7 +1295,12 @@ void config_screen_update(struct config_screen *screen, static int config_screen_post(struct nc_scr *scr) { struct config_screen *screen = config_screen_from_scr(scr); - screen->show_subset = false; + + /* We may have been posted after an auth action completed */ + if (screen->exit) { + screen->on_exit(screen->cui); + return 0; + } if (screen->need_update) { config_screen_draw(screen, screen->cui->config, @@ -1136,7 +1350,6 @@ struct config_screen *config_screen_init(struct cui *cui, screen->field_x = 17; screen->ipmi_override = false; - screen->show_subset = false; screen->scr.frame.ltitle = talloc_strdup(screen, _("Petitboot System Configuration"));