]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[cmdline] Add "imgset" command
authorMichael Brown <mcb30@ipxe.org>
Tue, 14 Jul 2026 11:45:32 +0000 (12:45 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 14 Jul 2026 12:09:01 +0000 (13:09 +0100)
A commonly requested feature is to allow a setting to be populated
with the contents of an HTTP response.  This currently requires a
somewhat ugly workaround of having the HTTP endpoint generate an iPXE
executable script fragment that includes the "#!ipxe" shebang and the
relevant "set" command.

For HTTP endpoints that are under the end user's control, this
workaround is viable (though still ugly).  For HTTP endpoints that are
outside the user's control (such as the AWS metadata endpoints), this
workaround cannot be used.

Add an "imgset" command that can be used to store downloaded content
directly into a setting.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/config/config.c
src/config/general.h
src/hci/commands/image_set_cmd.c [new file with mode: 0644]

index 90e4a916c4427ffc184a9c753d389528ff313468..e41833b6623b5fa689b2dbe13a86b7782438ea83 100644 (file)
@@ -309,6 +309,9 @@ REQUIRE_OBJECT ( image_crypt_cmd );
 #ifdef FDT_CMD
 REQUIRE_OBJECT ( fdt_cmd );
 #endif
+#ifdef IMAGE_SET_CMD
+REQUIRE_OBJECT ( image_set_cmd );
+#endif
 
 /*
  * Drag in miscellaneous objects
index 19fb3397973164c06d7887871fab3f560b2afcf7..19e5390ab4f61fbeb41c539b33b750284c5d9b46 100644 (file)
@@ -100,6 +100,7 @@ FILE_SECBOOT ( PERMITTED );
 #define IMAGE_ARCHIVE_CMD      /* Archive image management commands */
 //#define IMAGE_CRYPT_CMD      /* Image encryption management commands */
 //#define IMAGE_MEM_CMD                /* Read memory command */
+#define IMAGE_SET_CMD          /* Image setting commands */
 //#define IMAGE_TRUST_CMD      /* Image trust management commands */
 //#define IPSTAT_CMD           /* IP statistics commands */
 #define IWMGMT_CMD             /* Wireless interface management commands */
diff --git a/src/hci/commands/image_set_cmd.c b/src/hci/commands/image_set_cmd.c
new file mode 100644 (file)
index 0000000..6200261
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2026 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * 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; either version 2 of the
+ * License, or any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+FILE_SECBOOT ( PERMITTED );
+
+#include <string.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <ipxe/settings.h>
+#include <usr/imgmgmt.h>
+
+/** @file
+ *
+ * Image setting commands
+ *
+ */
+
+/** "imgset" options */
+struct imgset_options {
+       /** Keep original image */
+       int keep;
+       /** Download timeout */
+       unsigned long timeout;
+};
+
+/** "imgset" option list */
+static struct option_descriptor imgset_opts[] = {
+       OPTION_DESC ( "keep", 'k', no_argument,
+                     struct imgset_options, keep, parse_flag ),
+       OPTION_DESC ( "timeout", 't', required_argument,
+                     struct imgset_options, timeout, parse_timeout ),
+};
+
+/** "imgset" command descriptor */
+static struct command_descriptor imgset_cmd =
+       COMMAND_DESC ( struct imgset_options, imgset_opts, 2, 2, NULL );
+
+/**
+ * The "imgset" command
+ *
+ * @v argc             Argument count
+ * @v argv             Argument list
+ * @ret rc             Return status code
+ */
+static int imgset_exec ( int argc, char **argv ) {
+       struct imgset_options opts;
+       struct named_setting setting;
+       struct image *image;
+       int rc;
+
+       /* Parse options */
+       if ( ( rc = parse_options ( argc, argv, &imgset_cmd, &opts ) ) != 0 )
+               goto err_parse;
+
+       /* Parse setting name */
+       if ( ( rc = parse_autovivified_setting ( argv[optind++],
+                                                &setting ) ) != 0 )
+               goto err_setting;
+
+       /* Acquire image */
+       if ( ( rc = imgacquire ( argv[optind], opts.timeout, &image ) ) != 0 )
+               goto err_acquire;
+
+       /* Store setting value */
+       if ( ( rc = store_setting ( setting.settings, &setting.setting,
+                                   image->data, image->len ) ) != 0 ) {
+               printf ( "Could not store \"%s\": %s\n",
+                        setting.setting.name, strerror ( rc ) );
+               goto err_store;
+       }
+
+       /* Success */
+       rc = 0;
+
+ err_store:
+       /* Discard image unless --keep was specified */
+       if ( ! opts.keep )
+               unregister_image ( image );
+ err_acquire:
+ err_setting:
+ err_parse:
+       return rc;
+}
+
+/* Image setting commands */
+COMMAND ( imgset, imgset_exec );