#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <libintl.h>
-#include <syslog.h>
#include <pakfire/arch.h>
#include <pakfire/dependencies.h>
PyObject* PyExc_CheckError;
PyObject* PyExc_CheckFileVerificationError;
-struct pakfire_ctx* pakfire_ctx = NULL;
-
-static PyObject* setup_logger(void) {
- PyObject* logging = NULL;
- PyObject* logger = NULL;
-
- // import logging
- logging = PyImport_ImportModule("logging");
- if (!logging)
- goto ERROR;
-
- // logging.getLogger("pakfire")
- logger = PyObject_CallMethod(logging, "getLogger", "s", "pakfire");
- if (!logger)
- goto ERROR;
-
-ERROR:
- Py_XDECREF(logging);
-
- return logger;
-}
-
-static void __pakfire_log_callback(void* data, int level, const char* file, int line,
- const char* fn, const char* format, va_list args) {
- PyObject* logger = (PyObject*)data;
- PyObject* result = NULL;
- char* buffer = NULL;
- int r;
-
- PyObject* exception = NULL;
- PyObject* type = NULL;
- PyObject* value = NULL;
- PyObject* traceback = NULL;
-
- // Do nothing if the logger does not exist
- if (!logger)
- return;
-
- // Translate priority to Python logging priorities
- switch (level) {
- case LOG_DEBUG:
- level = 10;
- break;
-
- case LOG_INFO:
- level = 20;
- break;
-
- case LOG_ERR:
- level = 40;
- break;
-
- // Drop messages of an unknown level
- default:
- return;
- }
-
- PyGILState_STATE state = PyGILState_Ensure();
-
- // Format the log line
- r = vasprintf(&buffer, format, args);
- if (r < 0)
- goto ERROR;
-
- // Remove trailing newline
- if (buffer[r - 1] == '\n')
- r--;
-
- // Call the logger
- result = PyObject_CallMethod(logger, "log", "is#", level, buffer, r);
- if (!result)
- goto ERROR;
-
-ERROR:
- /*
- We cannot really catch any Python errors here, since we cannot send
- any error codes up the chain.
-
- So, in order to debug the problem, We will check if an exception has
- occurred and if so, print it to the console.
- */
- exception = PyErr_Occurred();
- if (exception) {
- PyErr_Print();
-
- // Fetch the exception and destroy it
- PyErr_Fetch(&type, &value, &traceback);
-
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
- }
-
- if (buffer)
- free(buffer);
- Py_XDECREF(result);
-
- // Release the GIL
- PyGILState_Release(state);
-}
-
-static int initialize_context(void) {
- PyObject* logger = NULL;
- int r;
-
- // Create a new context
- r = pakfire_ctx_create(&pakfire_ctx, NULL);
- if (r) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto ERROR;
- }
-
- // Setup the python logger
- logger = setup_logger();
- if (r)
- goto ERROR;
-
- // Pass all log messages to Python
- pakfire_ctx_set_log_callback(pakfire_ctx, __pakfire_log_callback, logger);
- Py_INCREF(logger);
-
- // Set the log level to DEBUG
- pakfire_ctx_set_log_level(pakfire_ctx, LOG_DEBUG);
-
- goto CLEANUP;
-
-ERROR:
- if (pakfire_ctx)
- pakfire_ctx_unref(pakfire_ctx);
-
-CLEANUP:
- Py_XDECREF(logger);
-
- return r;
-}
-
-static PyObject* _pakfire_set_cache_path(PyObject* self, PyObject* args) {
- const char* path = NULL;
- int r;
-
- if (!PyArg_ParseTuple(args, "s", &path))
- return NULL;
-
- // Set the cache path
- r = pakfire_ctx_set_cache_path(pakfire_ctx, path);
- if (r) {
- errno = -r;
- PyErr_SetFromErrno(PyExc_OSError);
-
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject* _pakfire_set_log_level(PyObject* self, PyObject* args) {
- int level = 0;
-
- if (!PyArg_ParseTuple(args, "i", &level))
- return NULL;
-
- // Set the log level
- pakfire_ctx_set_log_level(pakfire_ctx, level);
-
- Py_RETURN_NONE;
-}
-
static PyObject* _pakfire_supported_arches(void) {
int r;
}
static PyMethodDef pakfireModuleMethods[] = {
- {
- "set_cache_path",
- (PyCFunction)_pakfire_set_cache_path,
- METH_VARARGS,
- NULL,
- },
- {
- "set_log_level",
- (PyCFunction)_pakfire_set_log_level,
- METH_VARARGS,
- NULL,
- },
{"supported_arches", (PyCFunction)_pakfire_supported_arches, METH_NOARGS, NULL },
{
"version_compare",
if (PyModule_AddIntMacro(module, PAKFIRE_KEY_ALGO_ED25519) < 0)
goto ERROR;
- // Initialize the context
- r = initialize_context();
- if (r)
- goto ERROR;
-
return module;
ERROR:
#include <pakfire/buildservice.h>
#include "buildservice.h"
-
-extern struct pakfire_ctx* pakfire_ctx;
+#include "ctx.h"
static PyObject* BuildService_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
BuildServiceObject* self = (BuildServiceObject *)type->tp_alloc(type, 0);
}
static int BuildService_init(BuildServiceObject* self, PyObject* args, PyObject* kwds) {
+ CtxObject* ctx = NULL;
int r;
- r = pakfire_buildservice_create(&self->service, pakfire_ctx);
+ if (!PyArg_ParseTuple(args, "O!", &CtxType, &ctx))
+ return -1;
+
+ r = pakfire_buildservice_create(&self->service, ctx->ctx);
if (r) {
errno = -r;
# #
#############################################################################*/
+#define PY_SSIZE_T_CLEAN
#include <Python.h>
+#include <syslog.h>
#include <pakfire/ctx.h>
return (PyObject *)self;
}
+static void Ctx_log_callback(void* data, int level, const char* file, int line,
+ const char* fn, const char* format, va_list args) {
+ PyObject* logger = (PyObject*)data;
+ PyObject* result = NULL;
+ char* buffer = NULL;
+ int r;
+
+ PyObject* exception = NULL;
+ PyObject* type = NULL;
+ PyObject* value = NULL;
+ PyObject* traceback = NULL;
+
+ // Do nothing if the logger does not exist
+ if (!logger)
+ return;
+
+ // Translate priority to Python logging priorities
+ switch (level) {
+ case LOG_DEBUG:
+ level = 10;
+ break;
+
+ case LOG_INFO:
+ level = 20;
+ break;
+
+ case LOG_ERR:
+ level = 40;
+ break;
+
+ // Drop messages of an unknown level
+ default:
+ return;
+ }
+
+ PyGILState_STATE state = PyGILState_Ensure();
+
+ // Format the log line
+ r = vasprintf(&buffer, format, args);
+ if (r < 0)
+ goto ERROR;
+
+ // Remove trailing newline
+ if (buffer[r - 1] == '\n')
+ r--;
+
+ // Call the logger
+ result = PyObject_CallMethod(logger, "log", "is#", level, buffer, r);
+ if (!result)
+ goto ERROR;
+
+ERROR:
+ /*
+ We cannot really catch any Python errors here, since we cannot send
+ any error codes up the chain.
+
+ So, in order to debug the problem, We will check if an exception has
+ occurred and if so, print it to the console.
+ */
+ exception = PyErr_Occurred();
+ if (exception) {
+ PyErr_Print();
+
+ // Fetch the exception and destroy it
+ PyErr_Fetch(&type, &value, &traceback);
+
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ }
+
+ if (buffer)
+ free(buffer);
+ Py_XDECREF(result);
+
+ // Release the GIL
+ PyGILState_Release(state);
+}
+
+static void Ctx___set_logger(CtxObject* self, PyObject* logger) {
+ // Dereference the old logger
+ Py_XDECREF(self->logger);
+
+ // Store the new logger
+ self->logger = logger;
+ Py_INCREF(self->logger);
+
+ // Set the logger
+ pakfire_ctx_set_log_callback(self->ctx, Ctx_log_callback, self->logger);
+}
+
+static int Ctx_setup_logging(CtxObject* self) {
+ PyObject* logging = NULL;
+ PyObject* logger = NULL;
+ int r = -1;
+
+ // import logging
+ logging = PyImport_ImportModule("logging");
+ if (!logging)
+ goto ERROR;
+
+ // logging.getLogger("pakfire")
+ logger = PyObject_CallMethod(logging, "getLogger", "s", "pakfire");
+ if (!logger)
+ goto ERROR;
+
+ // Set default logger
+ Ctx___set_logger(self, logger);
+
+ERROR:
+ Py_XDECREF(logging);
+ Py_XDECREF(logger);
+
+ return r;
+}
+
static int Ctx_init(CtxObject* self, PyObject* args, PyObject* kwargs) {
char* kwlist[] = { (char*)"path", NULL };
const char* path = NULL;
return -1;
}
+ // Set the log level to DEBUG
+ pakfire_ctx_set_log_level(self->ctx, LOG_DEBUG);
+
return 0;
}
if (self->ctx)
pakfire_ctx_unref(self->ctx);
+ Py_XDECREF(self->logger);
+
Py_TYPE(self)->tp_free((PyObject *)self);
}
+// Logging
+
+static PyObject* Ctx_set_logger(CtxObject* self, PyObject* args) {
+ PyObject* logger = NULL;
+
+ if (!PyArg_ParseTuple(args, "O", &logger))
+ return NULL;
+
+ // XXX Check if we have a log method
+
+ // Set the logger
+ Ctx___set_logger(self, logger);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* Ctx_set_cache_path(CtxObject* self, PyObject* value) {
+ const char* path = NULL;
+ int r;
+
+ // Fetch the path
+ path = PyUnicode_AsUTF8(value);
+ if (!path)
+ return NULL;
+
+ // Set the cache path
+ r = pakfire_ctx_set_cache_path(self->ctx, path);
+ if (r) {
+ errno = -r;
+ PyErr_SetFromErrno(PyExc_OSError);
+
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef Ctx_methods[] = {
+ {
+ "set_logger",
+ (PyCFunction)Ctx_set_logger,
+ METH_VARARGS,
+ NULL,
+ },
{ NULL },
};
static struct PyGetSetDef Ctx_getsetters[] = {
+ {
+ "cache_path",
+ NULL,
+ (setter)Ctx_set_cache_path,
+ NULL,
+ NULL,
+ },
{ NULL },
};
typedef struct {
PyObject_HEAD
struct pakfire_ctx* ctx;
+
+ PyObject* logger;
} CtxObject;
extern PyTypeObject CtxType;
#include "repo.h"
#include "util.h"
-extern struct pakfire_ctx* pakfire_ctx;
-
PyObject* new_package(PyTypeObject* type, struct pakfire_package* pkg) {
PackageObject* self = (PackageObject *)type->tp_alloc(type, 0);
if (self) {
static PyObject* Package_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
PackageObject* self = (PackageObject *)type->tp_alloc(type, 0);
if (self) {
+ self->ctx = NULL;
self->package = NULL;
}
static void Package_dealloc(PackageObject* self) {
pakfire_package_unref(self->package);
+ if (self->ctx)
+ pakfire_ctx_unref(self->ctx);
+
Py_TYPE(self)->tp_free((PyObject *)self);
}
&name, &evr, &arch))
return -1;
+ // Store a reference to the context
+ self->ctx = pakfire_ctx_ref(pakfire->ctx);
+
int r = pakfire_package_create(&self->package, pakfire->pakfire, repo->repo, name, evr, arch);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
int r;
// Create a new packagelist
- r = pakfire_packagelist_create(&list, pakfire_ctx);
+ r = pakfire_packagelist_create(&list, self->ctx);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
goto ERROR;
#include <Python.h>
+#include <pakfire/ctx.h>
#include <pakfire/package.h>
#include "pakfire.h"
typedef struct {
PyObject_HEAD
+ struct pakfire_ctx* ctx;
struct pakfire_package* package;
} PackageObject;
#include <pakfire/util.h>
#include "archive.h"
+#include "ctx.h"
#include "errors.h"
#include "key.h"
#include "pakfire.h"
#include "repo.h"
#include "util.h"
-extern struct pakfire_ctx* pakfire_ctx;
-
static PyObject* Pakfire_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
PakfireObject* self = (PakfireObject *)type->tp_alloc(type, 0);
- if (self)
+ if (self) {
+ self->ctx = NULL;
self->pakfire = NULL;
+ }
return (PyObject *)self;
}
static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
char* kwlist[] = {
+ "ctx",
"path",
"arch",
"conf",
NULL,
};
+ CtxObject* ctx = NULL;
const char* path = NULL;
const char* arch = NULL;
PyObject* conf = Py_None;
FILE* fconf = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", kwlist,
- &path, &arch, &conf))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|zzO", kwlist,
+ &CtxType, &ctx, &path, &arch, &conf))
goto ERROR;
// Map the configuration
Py_BEGIN_ALLOW_THREADS
+ // Store a reference to the context
+ self->ctx = pakfire_ctx_ref(ctx->ctx);
+
// Create a new Pakfire instance
- r = pakfire_create(&self->pakfire, pakfire_ctx, path, arch, fconf, flags);
+ r = pakfire_create(&self->pakfire, self->ctx, path, arch, fconf, flags);
Py_END_ALLOW_THREADS
Py_END_ALLOW_THREADS
}
+ if (self->ctx)
+ pakfire_ctx_unref(self->ctx);
Py_TYPE(self)->tp_free((PyObject *)self);
}
return NULL;
// Generate a new key
- int r = pakfire_key_generate(&key, pakfire_ctx, algo, comment);
+ int r = pakfire_key_generate(&key, self->ctx, algo, comment);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
return NULL;
// Import the key
- r = pakfire_key_import(&key, pakfire_ctx, f);
+ r = pakfire_key_import(&key, self->ctx, f);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
goto ERROR;
return NULL;
// Create a new list
- r = pakfire_packagelist_create(&list, pakfire_ctx);
+ r = pakfire_packagelist_create(&list, self->ctx);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
goto ERROR;
Py_BEGIN_ALLOW_THREADS
// Create a new list
- r = pakfire_packagelist_create(&list, pakfire_ctx);
+ r = pakfire_packagelist_create(&list, self->ctx);
if (r) {
Py_BLOCK_THREADS
PyErr_SetFromErrno(PyExc_OSError);
if (name_only)
flags |= PAKFIRE_SEARCH_NAME_ONLY;
- r = pakfire_packagelist_create(&list, pakfire_ctx);
+ r = pakfire_packagelist_create(&list, self->ctx);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
goto ERROR;
typedef struct {
PyObject_HEAD
+ struct pakfire_ctx* ctx;
struct pakfire* pakfire;
// Callbacks