ui/ncurses: Implement F10-F12 for autoboot device control
authorJeremy Kerr <jk@ozlabs.org>
Tue, 3 Jul 2018 06:34:47 +0000 (16:34 +1000)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 10 Jul 2018 03:46:12 +0000 (13:46 +1000)
Add a few mappings to specify temporary autoboot settings:

  F10: Only autoboot from disk
  F11: Only autoboot from USB devices
  F12: Only autoboot from network

These use the new code to prevent cancelling autoboot.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
discover/device-handler.c
ui/common/discover-client.c
ui/common/discover-client.h
ui/ncurses/nc-cui-help.c
ui/ncurses/nc-cui.c
ui/ncurses/nc-cui.h

index b8e933088b28f5c7eb3aed788287af48ab0df365..72dda756ca958e627b4553a9fbc154d51c9640e3 100644 (file)
@@ -935,13 +935,38 @@ static void set_default(struct device_handler *handler,
        default_timeout(handler);
 }
 
+static char *autoboot_option_desc(void *ctx, const struct autoboot_option *opt)
+{
+       const char *type, *val;
+
+       if (opt->boot_type == BOOT_DEVICE_TYPE) {
+               type = _("device type");
+               val = device_type_display_name(opt->type);
+       } else if (opt->boot_type == BOOT_DEVICE_UUID) {
+               type = _("device UUID");
+               val = opt->uuid;
+       } else {
+               type = _("unknown specifier");
+               val = NULL;
+       }
+
+       return talloc_asprintf(ctx, "%s = %s", type, val);
+}
+
 void device_handler_apply_temp_autoboot(struct device_handler *handler,
                struct autoboot_option *opt)
 {
        unsigned int i;
+       char *desc;
 
        handler->temp_autoboot = talloc_steal(handler, opt);
 
+       desc = autoboot_option_desc(handler, opt);
+       device_handler_status_info(handler,
+                       _("Applying temporary autoboot override: %s"),
+                       desc);
+       talloc_free(desc);
+
        if (!handler->autoboot_enabled)
                return;
 
index 784154e3ae589df8573213ef97f6f4231097b299..88d0b4e3a8cea9eb31e4f129800d261f64a0b3ff 100644 (file)
@@ -453,3 +453,21 @@ int discover_client_send_plugin_install(struct discover_client *client,
 
        return pb_protocol_write_message(client->fd, message);
 }
+
+int discover_client_send_temp_autoboot(struct discover_client *client,
+               const struct autoboot_option *opt)
+{
+       struct pb_protocol_message *message;
+       int len;
+
+       len = pb_protocol_temp_autoboot_len(opt);
+
+       message = pb_protocol_create_message(client,
+                       PB_PROTOCOL_ACTION_TEMP_AUTOBOOT, len);
+       if (!message)
+               return -1;
+
+       pb_protocol_serialise_temp_autoboot(opt, message->payload, len);
+
+       return pb_protocol_write_message(client->fd, message);
+}
index 7224691abeff54f186fb1b9fe12fb93ca644fc53..2a2ea288f4c9842049da09318bf8213b39a8d808 100644 (file)
@@ -102,4 +102,8 @@ int discover_client_send_url(struct discover_client *client, char *url);
 int discover_client_send_plugin_install(struct discover_client *client,
                char *file);
 
+/* send a temporary autoboot override */
+int discover_client_send_temp_autoboot(struct discover_client *client,
+               const struct autoboot_option *opt);
+
 #endif
index 7d97ba5db6779d11bacab2ec960f8c065e9d02ea..0e57b776041dcbc86207babc2840d62cd49c3226 100644 (file)
@@ -26,5 +26,14 @@ option.\n\
 To retreive new boot options from a remote configuration file, select \
 the 'Retrieve config from URL' option.\n\
 \n\
+To restrict petitboot to only autobooting from a specific device type, the \
+following keys are available:\n\
+\n\
+  F10: Only autoboot from disk\n\
+  F11: Only autoboot from USB devices\n\
+  F12: Only autoboot from network\n\
+\n\
+Unlike other keys, these do not cancel automatic boot.\n\
+\n\
 To close the Petitboot interface, type X (exit).\n"
 );
index 87540cad66243f8ac56267122879ab43836005fb..87d2503d94a4042c2b63f41f5ecc69d71619a245 100644 (file)
@@ -59,6 +59,27 @@ static struct pmenu *plugin_menu_init(struct cui *cui);
 
 static void cui_cancel_autoboot_on_exit(struct cui *cui);
 
+static struct {
+       int key;
+       struct autoboot_option opt;
+} autoboot_override_keys[] = {
+       { KEY_F(10), {
+                       .boot_type = BOOT_DEVICE_TYPE,
+                       .type = DEVICE_TYPE_DISK,
+               },
+       },
+       { KEY_F(11), {
+                       .boot_type = BOOT_DEVICE_TYPE,
+                       .type = DEVICE_TYPE_USB,
+               },
+       },
+       { KEY_F(12), {
+                       .boot_type = BOOT_DEVICE_TYPE,
+                       .type = DEVICE_TYPE_NETWORK,
+               },
+       },
+};
+
 static bool lockdown_active(void)
 {
 #if defined(SIGNED_BOOT) && defined(HARD_LOCKDOWN)
@@ -527,22 +548,50 @@ struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr)
        return old;
 }
 
+static bool set_temp_autoboot_opt(struct cui *cui, struct autoboot_option *opt)
+{
+       cui->autoboot_opt = opt;
+       if (cui->client)
+               discover_client_send_temp_autoboot(cui->client, opt);
+
+       return true;
+}
+
 static bool key_cancels_boot(int key)
 {
+       unsigned int i;
+
        if (key == 0xc)
                return false;
 
+       for (i = 0; i < ARRAY_SIZE(autoboot_override_keys); i++)
+               if (key == autoboot_override_keys[i].key)
+                       return false;
+
        return true;
 }
 
 static bool process_global_keys(struct cui *cui, int key)
 {
+       unsigned int i;
+
        switch (key) {
        case 0xc:
                if (cui->current && cui->current->main_ncw)
                        wrefresh(curscr);
                return true;
        }
+
+       /* check for autoboot override keys */
+       for (i = 0; i < ARRAY_SIZE(autoboot_override_keys); i++) {
+               if (key != autoboot_override_keys[i].key)
+                       continue;
+
+               pb_log("Sending temporary autoboot override\n");
+               set_temp_autoboot_opt(cui, &autoboot_override_keys[i].opt);
+               return true;
+       }
+
        return false;
 }
 
@@ -1428,6 +1477,12 @@ static int cui_server_wait(void *arg)
                        pb_log("Aborting default boot on pb-discover connect\n");
                        discover_client_cancel_default(cui->client);
                }
+
+               if (cui->autoboot_opt) {
+                       pb_log("Sending autoboot override on pb-discover connect\n");
+                       discover_client_send_temp_autoboot(cui->client,
+                                       cui->autoboot_opt);
+               }
        }
 
        return 0;
index b310f4a5662f7b238f4cf6c84294bdd40442971b..4997f4b5ff4734995f6c9b3ce03173026b0b97d9 100644 (file)
@@ -52,6 +52,7 @@ struct cui_opt_data {
 struct cui {
        enum pb_nc_sig c_sig;
        bool has_input;
+       struct autoboot_option *autoboot_opt;
        sig_atomic_t abort;
        sig_atomic_t resize;
        struct nc_scr *current;