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;
+}