]> git.ipfire.org Git - pakfire.git/commitdiff
pakfire: Make passing path optional
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 21 Mar 2021 13:09:20 +0000 (13:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 21 Mar 2021 13:10:05 +0000 (13:10 +0000)
This will automatically allocate a directory which will be used to
create a temporary pakfire environment

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/util.h
src/libpakfire/pakfire.c
src/libpakfire/util.c
src/pakfire/cli.py

index 34f8f8593d0faaeee6da89490b4532b78f2bf8e5..13b83a24c75e040d183df46fabc41491ae22c391 100644 (file)
@@ -53,7 +53,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
        const char* arch = NULL;
        int offline = 0;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|zp", kwlist, &path, &arch, &offline))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzp", kwlist, &path, &arch, &offline))
                return -1;
 
        // Create a new Pakfire instance
@@ -65,12 +65,6 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
                                PyErr_SetString(PyExc_ValueError, "Invalid architecture or path");
                                break;
 
-                       // path does not exist
-                       case ENOENT:
-                               PyErr_Format(PyExc_FileNotFoundError,
-                                       "%s does not exist or is not a directory", path);
-                               break;
-
                        // Anything else
                        default:
                                PyErr_SetFromErrno(PyExc_OSError);
index d63f47cc58efc3b24c4364a852dd027318a2959e..531032d14ae46380d338db316175487ffc354dd1 100644 (file)
@@ -67,6 +67,8 @@ time_t pakfire_path_age(const char* path);
 char* pakfire_hexlify(const char* digest, const size_t length);
 
 FILE* pakfire_mktemp(char* path);
+char* pakfire_mkdtemp(char* path);
+int pakfire_rmtree(const char* path, int flags);
 
 // JSON Stuff
 
index 5c27032cef155f2a44a3b215f256bb7c5c003b72..9f15401a02f02409a7ea246536d730356f1f40f0 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <ctype.h>
 #include <errno.h>
-#include <ftw.h>
 #include <linux/limits.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -68,6 +67,8 @@ struct _Pakfire {
 
        int activated;
        int nrefs;
+
+       int destroy_on_free;
 };
 
 static int log_priority(const char* priority) {
@@ -137,6 +138,12 @@ ERROR:
 static void pakfire_free(Pakfire pakfire) {
        DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire);
 
+       if (pakfire->destroy_on_free) {
+               DEBUG(pakfire, "Destroying %s\n", pakfire->path);
+
+               pakfire_rmtree(pakfire->path, 0);
+       }
+
        pakfire_repo_free_all(pakfire);
 
        if (pakfire->pool)
@@ -167,7 +174,8 @@ static int pakfire_safety_checks(Pakfire pakfire) {
 }
 
 PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char* arch) {
-       int r;
+       char tempdir[PATH_MAX] = PAKFIRE_PRIVATE_DIR "/tmp/XXXXXX";
+       int r = 1;
 
        // Default to the native architecture
        if (!arch)
@@ -180,17 +188,11 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char
        }
 
        // Path must be absolute
-       if (!pakfire_string_startswith(path, "/")) {
+       if (path && !pakfire_string_startswith(path, "/")) {
                errno = EINVAL;
                return 1;
        }
 
-       // Check if path exists
-       if (!pakfire_path_isdir(path)) {
-               errno = ENOENT;
-               return 1;
-       }
-
        // Check if we are running as root
        uid_t uid = getuid();
        if (uid != 0) {
@@ -204,6 +206,16 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char
 
        p->nrefs = 1;
 
+       // Generate a random path if none is set
+       if (!path) {
+               path = pakfire_mkdtemp(tempdir);
+               if (!path)
+                       goto ERROR;
+
+               // Destroy everything when done
+               p->destroy_on_free = 1;
+       }
+
        // Set path
        snprintf(p->path, sizeof(p->path) - 1, "%s", path);
 
@@ -709,23 +721,13 @@ int pakfire_make_cache_path(Pakfire pakfire, char* path, size_t length,
        return 0;
 }
 
-static int _unlink(const char* path, const struct stat* stat, int typeflag, struct FTW* ftwbuf) {
-       return remove(path);
-}
-
 PAKFIRE_EXPORT int pakfire_cache_destroy(Pakfire pakfire, const char* path) {
        char cache_path[PATH_MAX];
 
        pakfire_make_cache_path(pakfire, cache_path, sizeof(cache_path) - 1, "%s", path);
 
        // Completely delete the tree of files
-       int r = nftw(cache_path, _unlink, 64, FTW_DEPTH|FTW_PHYS);
-
-       // It is okay if the path doesn't exist
-       if (r < 0 && errno == ENOENT)
-               r = 0;
-
-       return r;
+       return pakfire_rmtree(cache_path, 0);
 }
 
 PAKFIRE_EXPORT pakfire_log_function_t pakfire_log_get_function(Pakfire pakfire) {
index 28f5dad526a7463c9eda3135229e8896c4cea658..ec6ea4879d8bb0c77b5d3857e2f7ea29f1cbb6c0 100644 (file)
@@ -21,6 +21,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <ftw.h>
 #include <libgen.h>
 #include <math.h>
 #include <stddef.h>
@@ -561,6 +562,28 @@ FILE* pakfire_mktemp(char* path) {
        return fdopen(fd, "w+");
 }
 
+char* pakfire_mkdtemp(char* path) {
+       int r = pakfire_mkparentdir(path);
+       if (r)
+               return NULL;
+
+       return mkdtemp(path);
+}
+
+static int _unlink(const char* path, const struct stat* stat, int typeflag, struct FTW* ftwbuf) {
+       return remove(path);
+}
+
+int pakfire_rmtree(const char* path, int flags) {
+       int r = nftw(path, _unlink, 64, flags|FTW_DEPTH|FTW_PHYS);
+
+       // Ignore if path didn't exist
+       if (r < 0 && errno == ENOENT)
+               r = 0;
+
+       return r;
+}
+
 // JSON Stuff
 
 static struct json_object* pakfire_json_parse(Pakfire pakfire, FILE* f) {
index fa469bd722c32053b653a75299d9a7526dfd220c..ef7163ca829d4878a333a2769a37eb3651f54a06 100644 (file)
@@ -44,6 +44,8 @@ from .constants import *
 from .i18n import _
 
 class Cli(object):
+       default_path = "/"
+
        def __init__(self):
                self.ui = ui.cli.CliUI()
 
@@ -188,7 +190,10 @@ class Cli(object):
                                help=_("Run pakfire in offline mode."))
 
        def pakfire(self, ns):
-               p = base.Pakfire(path=ns.root, offline=ns.offline)
+               p = base.Pakfire(
+                       path=ns.root if "root" in ns else self.default_path,
+                       offline=ns.offline,
+               )
 
                # Disable repositories.
                for repo_name in ns.disable_repo:
@@ -381,6 +386,8 @@ class Cli(object):
 
 
 class CliBuilder(Cli):
+       default_path = None
+
        def parse_cli(self):
                parser = argparse.ArgumentParser(
                        description = _("Pakfire builder command line interface"),