]> git.ipfire.org Git - pakfire.git/commitdiff
snapshots: Add function to create a new snapshot
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 18 Oct 2024 12:54:43 +0000 (12:54 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 18 Oct 2024 12:54:43 +0000 (12:54 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/include/pakfire/snapshot.h
src/libpakfire/pakfire.c
src/libpakfire/snapshot.c

index 987f48576c0940045f06d31262d4d4acb490539d..87acf16b1fb2ef97b025d4d417fec96e972bbee2 100644 (file)
@@ -86,6 +86,9 @@ int pakfire_search(struct pakfire* pakfire, const char* what, int flags,
 
 int pakfire_check(struct pakfire* pakfire, struct pakfire_filelist* errors);
 
+// Snapshots
+int pakfire_update_snapshot(struct pakfire* pakfire);
+
 #ifdef PAKFIRE_PRIVATE
 
 #include <sys/types.h>
index 845db993089d65eef2368f84f681d5a1f15fdc05..0e540b3cc25241e40de17e1c563ae7186925cda9 100644 (file)
@@ -42,6 +42,8 @@ const char* pakfire_snapshot_path(struct pakfire_snapshot* snapshot);
 int pakfire_snapshot_mount(struct pakfire_snapshot* snapshot, const char* path);
 int pakfire_snapshot_umount(struct pakfire_snapshot* snapshot);
 
-#endif
+int pakfire_snapshot_make(struct pakfire_snapshot** snapshot,
+       struct pakfire* pakfire, const char** packages);
 
+#endif /* PAKFIRE_PRIVATE */
 #endif /* PAKFIRE_SNAPSHOT_H */
index da88562f9658d24d1005817e46b35c037245225a..d17176e5924fdfce77a9824dd149bf864f847144 100644 (file)
@@ -1712,3 +1712,21 @@ ERROR:
 
        return r;
 }
+
+int pakfire_update_snapshot(struct pakfire* pakfire) {
+       struct pakfire_snapshot* snapshot = NULL;
+       int r;
+
+       const char* packages[] = {
+               "build-essential",
+               NULL,
+       };
+
+       // Make a new snapshot
+       r = pakfire_snapshot_make(&snapshot, pakfire, packages);
+
+       if (snapshot)
+               pakfire_snapshot_unref(snapshot);
+
+       return r;
+}
index d18eb3dbf2fc3e78dd9b43f599de0c621e6b7d0e..80b8b1f11ba4d85c8d39822bd52ebb0167d184cc 100644 (file)
@@ -349,3 +349,119 @@ int pakfire_snapshot_umount(struct pakfire_snapshot* snapshot) {
 
        return 0;
 }
+
+static int pakfire_snapshot_install_packages(struct pakfire* pakfire, const char** packages) {
+       struct pakfire_transaction* transaction = NULL;
+       int r;
+
+       // Create a new transaction
+       r = pakfire_transaction_create(&transaction, pakfire, 0);
+       if (r)
+               goto ERROR;
+
+       // Install all build dependencies
+       for (const char** p = packages; *p; p++) {
+               r = pakfire_transaction_request(transaction, PAKFIRE_JOB_INSTALL, *p, PAKFIRE_JOB_ESSENTIAL);
+               if (r < 0)
+                       goto ERROR;
+       }
+
+       // Also update everything that has already been installed
+       r = pakfire_transaction_request(transaction, PAKFIRE_JOB_SYNC, NULL, 0);
+       if (r < 0)
+               goto ERROR;
+
+       // Solve the transaction
+       r = pakfire_transaction_solve(transaction, 0, NULL);
+       if (r)
+               goto ERROR;
+
+       // Run the transaction
+       r = pakfire_transaction_run(transaction);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (transaction)
+               pakfire_transaction_unref(transaction);
+
+       return r;
+}
+
+/*
+       Creates a new snapshot
+*/
+int pakfire_snapshot_make(struct pakfire_snapshot** snapshot,
+               struct pakfire* pakfire, const char** packages) {
+       struct pakfire* p = NULL;
+       char snapshot_path[PATH_MAX];
+       char tmp[PATH_MAX];
+       const char* path = NULL;
+       char time[1024];
+       int r;
+
+       struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
+
+       // Store the current time
+       r = pakfire_strftime_now(time, "%Y-%m-%d-%H:%M:%S");
+       if (r < 0)
+               goto ERROR;
+
+       // Make the final snapshot path
+       r = pakfire_cache_path(pakfire, snapshot_path, "snapshots/%s", time);
+       if (r < 0)
+               goto ERROR;
+
+       // Make a new temporary path
+       r = pakfire_cache_path(pakfire, tmp, "%s", "snapshots/.XXXXXXX");
+       if (r < 0)
+               goto ERROR;
+
+       // Create the temporary directory
+       path = pakfire_mkdtemp(tmp);
+       if (!path) {
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Clone the Pakfire instance
+       r = pakfire_clone(&p, pakfire, tmp);
+       if (r < 0) {
+               CTX_ERROR(ctx, "Could not clone pakfire: %s\n", strerror(-r));
+               goto ERROR;
+       }
+
+       // Install packages
+       r = pakfire_snapshot_install_packages(p, packages);
+       if (r < 0)
+               goto ERROR;
+
+       // Close the pakfire instance
+       pakfire_unref(p);
+       p = NULL;
+
+       // Move the snapshot to its final place
+       r = rename(tmp, snapshot_path);
+       if (r < 0) {
+               CTX_ERROR(ctx, "Could not move the snapshot to %s: %m\n", snapshot_path);
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Open the snapshot
+       r = pakfire_snapshot_create(snapshot, ctx, snapshot_path);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (p)
+               pakfire_unref(p);
+       if (ctx)
+               pakfire_ctx_unref(ctx);
+
+       // Cleanup the temporary directory
+       if (r)
+               pakfire_rmtree(tmp, 0);
+
+       return r;
+}