]> git.ipfire.org Git - pakfire.git/commitdiff
pakfire: Read configuration from a file descriptor
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 2 Aug 2023 15:33:14 +0000 (15:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 2 Aug 2023 15:33:14 +0000 (15:33 +0000)
This is easier to handle especially when creating temporary environments
where we just want to shoot the configuration into Pakfire().

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/pakfire.c
src/pakfire/daemon.py
src/scripts/pakfire-builder.in
src/scripts/pakfire.in
tests/testsuite.c

index 94ef7ebdac174937c0554e21039f9ae5bf1d422b..b239c073836d3e7a5971cd5e651f41efa0a0e4d2 100644 (file)
@@ -193,24 +193,33 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        };
        const char* path = NULL;
        const char* arch = NULL;
-       const char* conf = NULL;
+       PyObject* conf = NULL;
        int offline = 0;
-       int r;
+       int r = 1;
+
+       FILE* fconf = NULL;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpzO", kwlist,
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpOO", kwlist,
                        &path, &arch, &self->callbacks.log, &offline, &conf, &self->callbacks.confirm))
-               return -1;
+               goto ERROR;
 
        // Check if log callback is callable
        if (self->callbacks.log && !PyCallable_Check(self->callbacks.log)) {
                PyErr_SetString(PyExc_TypeError, "logger must be callable\n");
-               return -1;
+               goto ERROR;
        }
 
        // Check if confirm callback is callable
        if (self->callbacks.confirm && !PyCallable_Check(self->callbacks.confirm)) {
                PyErr_SetString(PyExc_TypeError, "Confirm callback is not callable");
-               return -1;
+               goto ERROR;
+       }
+
+       // Map the configuration
+       if (conf) {
+               fconf = PyObject_AsFileHandle(conf, "r");
+               if (!fconf)
+                       goto ERROR;
        }
 
        int flags = 0;
@@ -226,7 +235,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        Py_BEGIN_ALLOW_THREADS
 
        // Create a new Pakfire instance
-       r = pakfire_create(&self->pakfire, path, arch, conf, flags,
+       r = pakfire_create(&self->pakfire, path, arch, fconf, flags,
                LOG_DEBUG, Pakfire_log_callback, self->callbacks.log);
 
        Py_END_ALLOW_THREADS
@@ -245,7 +254,8 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                                PyErr_SetFromErrno(PyExc_OSError);
                }
 
-               return -1;
+               r = -1;
+               goto ERROR;
     }
 
        // Configure confirm callback
@@ -256,7 +266,11 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                Py_INCREF(self->callbacks.confirm);
        }
 
-       return 0;
+ERROR:
+       if (fconf)
+               fclose(fconf);
+
+       return -r;
 }
 
 static void Pakfire_dealloc(PakfireObject* self) {
index 88589eca3ead5040412550c6d008a9578bf0da8d..094a2a2fc1a555839fda818bd2d108cb4105c2b0 100644 (file)
@@ -53,8 +53,7 @@ typedef void (*pakfire_status_callback)(struct pakfire* pakfire, void* data,
        int progress, const char* status);
 
 int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch,
-       const char* conf, int flags,
-       int loglevel, pakfire_log_callback log_callback, void* log_data);
+       FILE* conf, int flags, int loglevel, pakfire_log_callback log_callback, void* log_data);
 
 struct pakfire* pakfire_ref(struct pakfire* pakfire);
 struct pakfire* pakfire_unref(struct pakfire* pakfire);
index ac3ba0961f4388b5f2bb2e9df10fa27842d1ef71..c60eef691fa44f0317e288b34884324b3a810cf4 100644 (file)
@@ -608,52 +608,31 @@ static int pakfire_config_import_distro(struct pakfire* pakfire) {
        return 0;
 }
 
-static int pakfire_read_config(struct pakfire* pakfire, const char* path) {
-       char default_path[PATH_MAX];
+static int pakfire_read_config(struct pakfire* pakfire, FILE* f) {
        int r;
 
-       // Use default path if none set
-       if (!path) {
-               r = pakfire_path(pakfire, default_path, "%s", PAKFIRE_CONFIG_DIR "/general.conf");
-               if (r)
-                       return r;
-
-               path = default_path;
-       }
-
-       DEBUG(pakfire, "Reading configuration from %s\n", path);
-
-       FILE* f = fopen(path, "r");
-       if (!f) {
-               // Silently ignore when there is no default configuration file
-               if (*default_path && errno == ENOENT)
-                       return 0;
-
-               ERROR(pakfire, "Could not open configuration file %s: %m\n", path);
-               return 1;
-       }
+       DEBUG(pakfire, "Reading configuration\n");
 
        // Read configuration from file
-       r = pakfire_config_read(pakfire->config, f);
-       if (r) {
-               ERROR(pakfire, "Could not parse configuration file %s: %m\n", path);
-               goto ERROR;
+       if (f) {
+               r = pakfire_config_read(pakfire->config, f);
+               if (r) {
+                       ERROR(pakfire, "Could not parse configuration: %m\n");
+                       return r;
+               }
        }
 
        // Import distro configuration
        r = pakfire_config_import_distro(pakfire);
        if (r)
-               goto ERROR;
+               return r;
 
        // Read repository configuration
        r = pakfire_read_repo_config(pakfire);
        if (r)
-               goto ERROR;
-
-ERROR:
-       fclose(f);
+               return r;
 
-       return r;
+       return 0;
 }
 
 static int pakfire_read_os_release(struct pakfire* pakfire) {
@@ -815,7 +794,7 @@ ERROR:
 }
 
 PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
-               const char* arch, const char* conf, int flags,
+               const char* arch, FILE* conf, int flags,
                int loglevel, pakfire_log_callback log_callback, void* log_data) {
        char tempdir[PATH_MAX] = PAKFIRE_TMP_DIR "/pakfire-root-XXXXXX";
        char private_dir[PATH_MAX];
index 9467b7d781fd7d84561a3f1ca48cd5d8da067c37..3438e030009149fa4c41b2573c0c6f29f2fce4a9 100644 (file)
@@ -3,6 +3,7 @@
 import asyncio
 import functools
 import glob
+import io
 import json
 import logging
 import logging.handlers
@@ -380,14 +381,7 @@ class Worker(multiprocessing.Process):
                # Dump pakfire configuration
                log.debug("Pakfire configuration:\n%s" % conf)
 
-               # Write the configuration to file
-               f = tempfile.NamedTemporaryFile(delete=False)
-               if conf:
-                       f.write(conf.encode())
-               f.close()
-
-               # Return the path
-               return f.name
+               return io.StringIO(conf)
 
 
 class BuildLogger(object):
index 758f2bcd54a38ae6b9f7d2ebfc47bbba16e30f4b..e675a05700521142cf26e85fe3cd979a4f830c95 100644 (file)
@@ -190,7 +190,8 @@ class Cli(object):
                )
 
                # Create a new Pakfire instance
-               p = pakfire.Pakfire(arch=ns.arch, conf=conf, logger=logger.log)
+               with open(conf) as c:
+                       p = pakfire.Pakfire(arch=ns.arch, conf=c, logger=logger.log)
 
                # Enable/disable repositories
                for repo in p.repos:
index 451739d706ae052e3673b2ea3cb55cc8824b0540..43f8cb0f15fa2afc26f60b49c5b1d7b646f91c0a 100644 (file)
@@ -39,7 +39,7 @@ class Cli(object):
                        version="%%(prog)s %s" % pakfire.__version__)
 
                # Which configuration file to load?
-               parser.add_argument("--config", "-c", nargs="?",
+               parser.add_argument("--config", "-c", nargs="?", type=argparse.FileType("r"),
                        help=_("Configuration file"))
 
                # Enable/disable repositories
@@ -256,7 +256,7 @@ class Cli(object):
 
                # Create Pakfire instance
                p = pakfire.Pakfire(
-                       conf=args.config,
+                       conf=args.conf,
                        arch=args.arch,
                        path=args.root,
                        offline=args.offline,
index e90fd6f1acaf4b25b36d0f3256d5d9f3e2e4f858..519e0f2bd5282fa19293ccc8658ad81c35206d29 100644 (file)
@@ -34,6 +34,7 @@ struct testsuite ts;
 
 static int test_run(int i, struct test* t) {
        struct pakfire* p = NULL;
+       FILE* c = NULL;
 
        char root[PATH_MAX] = TEST_ROOTFS "/pakfire-test-XXXXXX";
        int r;
@@ -47,9 +48,16 @@ static int test_run(int i, struct test* t) {
 
        LOG("running %s (%s)\n", t->name, root);
 
+       // Open the configuration file
+       c = fopen(TEST_SRC_PATH "/pakfire.conf", "r");
+       if (!c) {
+               LOG("Could not open configuration file: %m\n");
+               r = 1;
+               goto ERROR;
+       }
+
        // Create a pakfire instance
-       r = pakfire_create(&t->pakfire, root, NULL, TEST_SRC_PATH "/pakfire.conf",
-               0, LOG_DEBUG, pakfire_log_stderr, NULL);
+       r = pakfire_create(&t->pakfire, root, NULL, c, 0, LOG_DEBUG, pakfire_log_stderr, NULL);
        if (r) {
                LOG("ERROR: Could not initialize pakfire: %m\n");
                goto ERROR;
@@ -88,6 +96,10 @@ ERROR:
                t->pakfire = NULL;
        }
 
+       // Close the configuration file
+       if (c)
+               fclose(c);
+
        // Cleanup root
        pakfire_rmtree(root, 0);