From 509aaad2e3666a1c25e950c58ff9307619e3b693 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 2 Aug 2023 15:33:14 +0000 Subject: [PATCH] pakfire: Read configuration from a file descriptor 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 --- src/_pakfire/pakfire.c | 32 ++++++++++++----- src/libpakfire/include/pakfire/pakfire.h | 3 +- src/libpakfire/pakfire.c | 45 +++++++----------------- src/pakfire/daemon.py | 10 ++---- src/scripts/pakfire-builder.in | 3 +- src/scripts/pakfire.in | 4 +-- tests/testsuite.c | 16 +++++++-- 7 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index 94ef7ebda..b239c0738 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -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) { diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 88589eca3..094a2a2fc 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -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); diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index ac3ba0961..c60eef691 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -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]; diff --git a/src/pakfire/daemon.py b/src/pakfire/daemon.py index 9467b7d78..3438e0300 100644 --- a/src/pakfire/daemon.py +++ b/src/pakfire/daemon.py @@ -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): diff --git a/src/scripts/pakfire-builder.in b/src/scripts/pakfire-builder.in index 758f2bcd5..e675a0570 100644 --- a/src/scripts/pakfire-builder.in +++ b/src/scripts/pakfire-builder.in @@ -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: diff --git a/src/scripts/pakfire.in b/src/scripts/pakfire.in index 451739d70..43f8cb0f1 100644 --- a/src/scripts/pakfire.in +++ b/src/scripts/pakfire.in @@ -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, diff --git a/tests/testsuite.c b/tests/testsuite.c index e90fd6f1a..519e0f2bd 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -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); -- 2.39.5