]> git.ozlabs.org Git - petitboot/commitdiff
discover/pxe-parser: Fix relative parsing for manual config files petitboot-1.6.x v1.6.6
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 12 Dec 2017 03:05:40 +0000 (14:05 +1100)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Thu, 14 Dec 2017 23:59:08 +0000 (10:59 +1100)
Manually specified config files are asynchronously downloaded by
device_handler_process_url() before being parsed. This overwrites the
'pxeconffile' parameter, causing the parser to create relative paths
relative to the downloaded file's path, not the original remote path.

Work around this by setting 'pxeconffile-local' instead to differentiate
between the original config file's location and the local copy.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
(cherry picked from commit a2d5a3e3cb55fe3583acaae44fabc7c3d7f8df50)

discover/device-handler.c
discover/pxe-parser.c
test/parser/Makefile.am
test/parser/test-pxe-discover-bootfile-async-file.c [new file with mode: 0644]

index 8ad885f68225c031efc6de9b0b9f570776a53662..82230154ba77d9a314f50d3a41fe184837197d40 100644 (file)
@@ -1356,7 +1356,7 @@ static void process_url_cb(struct load_url_result *result, void *data)
 
        mac = event_get_param(event, "mac");
        char *url = talloc_asprintf(event, "file://%s", result->local);
-       event_set_param(event, "pxeconffile", url);
+       event_set_param(event, "pxeconffile-local", url);
 
        dev = discover_device_create(handler, mac, event->device);
        ctx = device_handler_discover_context_create(handler, dev);
index aef43b8cdfc06737ad72d06fc7f76a4c1670473f..29d9c337678c23cb2fb7b1ef449206ffd041ea0b 100644 (file)
@@ -356,7 +356,7 @@ static struct conf_context *copy_context(void *ctx, struct discover_context *dc)
 
 static int pxe_parse(struct discover_context *dc)
 {
-       struct pb_url *pxe_base_url;
+       struct pb_url *pxe_base_url, *file_url;
        struct conf_context *conf = NULL;
        struct load_url_result *result;
        void *ctx = talloc_parent(dc);
@@ -385,13 +385,25 @@ static int pxe_parse(struct discover_context *dc)
                return -1;
 
        if (complete_url) {
+               /* Check if this file has already been downloaded */
+               if (event_get_param(dc->event, "pxeconffile-local"))
+                       file_url = pb_url_parse(dc, event_get_param(dc->event,
+                                               "pxeconffile-local"));
+               else
+                       file_url = dc->conf_url;
+
+               if (!file_url) {
+                       pb_log("%s: Failed to parse conf url!\n", __func__);
+                       goto out_conf;
+               }
+
                device_handler_status_dev_info(conf->dc->handler,
                        dc->device,
                        _("Requesting config %s"),
                        pb_url_to_string(conf->dc->conf_url));
 
                /* we have a complete URL; use this and we're done. */
-               result = load_url_async(conf->dc, conf->dc->conf_url,
+               result = load_url_async(conf->dc, file_url,
                                        pxe_conf_parse_cb, conf, NULL, ctx);
                if (!result) {
                        pb_log("load_url_async fails for %s\n",
index fa644fe3f98daa417cc49289e0eb0791965dd754..eb71a07dd1b76cafb3df7f361c4e296695a433e5 100644 (file)
@@ -71,6 +71,7 @@ parser_TESTS = \
        test/parser/test-pxe-discover-bootfile-pathprefix \
        test/parser/test-pxe-discover-bootfile-relative-conffile \
        test/parser/test-pxe-discover-bootfile-absolute-conffile \
+       test/parser/test-pxe-discover-bootfile-async-file \
        test/parser/test-unresolved-remove
 
 TESTS += $(parser_TESTS)
diff --git a/test/parser/test-pxe-discover-bootfile-async-file.c b/test/parser/test-pxe-discover-bootfile-async-file.c
new file mode 100644 (file)
index 0000000..af61659
--- /dev/null
@@ -0,0 +1,42 @@
+
+#include "parser-test.h"
+
+#if 0 /* PARSER_EMBEDDED_CONFIG */
+label linux
+kernel vmlinux
+initrd initrd
+#endif
+
+/**
+ * Manually specified conf files will be downloaded locally before being passed
+ * to the parser. Check that the parser correctly resolves relative paths to the
+ * actual source, rather than the local file path.
+ */
+
+void run_test(struct parser_test *test)
+{
+       struct discover_boot_option *opt;
+       struct discover_context *ctx;
+
+       test_read_conf_embedded_url(test, "file://tmp/conf.txt");
+
+       test_set_event_source(test);
+       test_set_event_param(test->ctx->event, "pxeconffile",
+                       "tftp://host/dir/fail.txt");
+       test_set_event_param(test->ctx->event, "pxeconffile-local",
+                       "file://tmp/conf.txt");
+
+       test_run_parser(test, "pxe");
+
+       ctx = test->ctx;
+
+       check_boot_option_count(ctx, 1);
+       opt = get_boot_option(ctx, 0);
+
+       check_name(opt, "linux");
+
+       check_resolved_url_resource(opt->boot_image,
+                       "tftp://host/dir/vmlinux");
+       check_resolved_url_resource(opt->initrd,
+                       "tftp://host/dir/initrd");
+}