src/libpakfire/pwd.c \
src/libpakfire/repo.c \
src/libpakfire/repolist.c \
- src/libpakfire/request.c \
src/libpakfire/scriptlet.c \
src/libpakfire/snapshot.c \
src/libpakfire/solution.c \
src/libpakfire/include/pakfire/pwd.h \
src/libpakfire/include/pakfire/repo.h \
src/libpakfire/include/pakfire/repolist.h \
- src/libpakfire/include/pakfire/request.h \
src/libpakfire/include/pakfire/scriptlet.h \
src/libpakfire/include/pakfire/snapshot.h \
src/libpakfire/include/pakfire/solution.h \
int r;
// Perform the installcheck
- r = pakfire_package_installcheck(self->package, &problem);
+ r = pakfire_package_installcheck(self->package, &problem, 0);
// Success!
if (r == 0)
#include <pakfire/key.h>
#include <pakfire/repo.h>
#include <pakfire/repolist.h>
-#include <pakfire/request.h>
#include <pakfire/transaction.h>
#include <pakfire/util.h>
// Do not install recommended packages
if (without_recommended)
- solver_flags |= PAKFIRE_REQUEST_WITHOUT_RECOMMENDED;
+ solver_flags |= PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED;
// Can the solver uninstall packages?
if (allow_uninstall)
- solver_flags |= PAKFIRE_REQUEST_ALLOW_UNINSTALL;
+ solver_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
// Can the solver downgrade packages?
if (allow_downgrade)
- solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
+ solver_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
Py_BEGIN_ALLOW_THREADS
transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
if (keep_dependencies)
- flags |= PAKFIRE_REQUEST_KEEP_DEPS;
+ flags |= PAKFIRE_JOB_KEEP_DEPS;
Py_BEGIN_ALLOW_THREADS
}
if (dryrun)
- transaction_flags = PAKFIRE_TRANSACTION_DRY_RUN;
+ transaction_flags |= PAKFIRE_TRANSACTION_DRY_RUN;
// Can the solver uninstall packages?
if (allow_uninstall)
- solver_flags |= PAKFIRE_REQUEST_ALLOW_UNINSTALL;
+ solver_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
// Can the solver downgrade packages?
if (allow_downgrade)
- solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
+ solver_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
Py_BEGIN_ALLOW_THREADS
return NULL;
if (keep_orphaned)
- flags |= PAKFIRE_REQUEST_KEEP_ORPHANED;
+ flags |= PAKFIRE_JOB_KEEP_ORPHANED;
Py_BEGIN_ALLOW_THREADS
#include <pakfire/private.h>
#include <pakfire/problem.h>
#include <pakfire/repo.h>
-#include <pakfire/request.h>
#include <pakfire/scriptlet.h>
#include <pakfire/snapshot.h>
#include <pakfire/solution.h>
#include <pakfire/string.h>
+#include <pakfire/transaction.h>
#include <pakfire/util.h>
#define CCACHE_DIR "/var/cache/ccache"
static int pakfire_build_install_package(struct pakfire* pakfire,
struct pakfire_package* pkg, void* p) {
- struct pakfire_request* request = (struct pakfire_request*)p;
+ struct pakfire_transaction* transaction = (struct pakfire_transaction*)p;
- return pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, pkg,
- PAKFIRE_REQUEST_ESSENTIAL);
+ return pakfire_transaction_request_package(transaction,
+ PAKFIRE_JOB_INSTALL, pkg, PAKFIRE_JOB_ESSENTIAL);
}
static int pakfire_build_install_test(struct pakfire_build* build) {
- struct pakfire_request* request = NULL;
+ struct pakfire_transaction* transaction = NULL;
struct pakfire_problem* problem = NULL;
struct pakfire_solution* solution = NULL;
const char* s = NULL;
int r;
- // Create a new request
- r = pakfire_request_create(&request, build->pakfire, 0);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, build->pakfire, 0);
if (r)
goto ERROR;
// Add all packages
- r = pakfire_packagelist_walk(build->packages, pakfire_build_install_package, request);
+ r = pakfire_packagelist_walk(build->packages, pakfire_build_install_package, transaction);
// Solve the request
- r = pakfire_request_solve(request, 0);
+ r = pakfire_transaction_solve(transaction, 0, NULL);
switch (r) {
// All okay
case 0:
// Walk through all problems
for (;;) {
- r = pakfire_request_next_problem(request, &problem);
+ r = pakfire_transaction_next_problem(transaction, &problem);
if (r)
goto ERROR;
ERROR:
if (r)
ERROR(build->pakfire, "Install test failed: %m\n");
- if (request)
- pakfire_request_unref(request);
if (problem)
pakfire_problem_unref(problem);
if (solution)
static int pakfire_build_install_source_package(
struct pakfire_build* build, struct pakfire_package* package) {
- struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
+ char* problems = NULL;
int r;
- // Create a new request
- r = pakfire_request_create(&request, build->pakfire, 0);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, build->pakfire, 0);
if (r)
goto ERROR;
- // Add the package
- r = pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, package,
- PAKFIRE_REQUEST_ESSENTIAL);
- if (r)
- goto ERROR;
-
- // Install all essential packages
+ // Request to install all essential packages
for (const char** p = PAKFIRE_BUILD_PACKAGES; *p; p++) {
- r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, *p, PAKFIRE_REQUEST_ESSENTIAL);
+ r = pakfire_transaction_request(transaction,
+ PAKFIRE_JOB_INSTALL, *p, PAKFIRE_JOB_ESSENTIAL);
if (r)
goto ERROR;
}
- // Solve the request
- r = pakfire_request_solve(request, 0);
+ // Add the source package
+ r = pakfire_transaction_request_package(transaction,
+ PAKFIRE_JOB_INSTALL, package, PAKFIRE_JOB_ESSENTIAL);
if (r)
goto ERROR;
- // Fetch the transaction
- r = pakfire_request_get_transaction(request, &transaction);
- if (r)
+ // Solve the transaction
+ r = pakfire_transaction_solve(transaction, 0, &problems);
+ if (r) {
+ if (problems)
+ ERROR(build->pakfire, "Could not install the source package:\n%s\n", problems);
+
goto ERROR;
+ }
// Set how many packages have been changed
const size_t changes = pakfire_transaction_count(transaction);
ERROR:
if (transaction)
pakfire_transaction_unref(transaction);
- if (request)
- pakfire_request_unref(request);
+ if (problems)
+ free(problems);
return r;
}
static int pakfire_build_mkimage_install_deps(struct pakfire_build* build,
const char* type) {
- struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
char requires[NAME_MAX];
+ char* problems = NULL;
int r;
// Format requires
if (r)
goto ERROR;
- // Create a new request
- r = pakfire_request_create(&request, build->pakfire, 0);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, build->pakfire, 0);
if (r) {
- ERROR(build->pakfire, "Could not create request: %m\n");
+ ERROR(build->pakfire, "Could not create transaction: %m\n");
goto ERROR;
}
// Add requires to the request
- r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, requires,
- PAKFIRE_REQUEST_ESSENTIAL);
+ r = pakfire_transaction_request(transaction,
+ PAKFIRE_JOB_INSTALL, requires, PAKFIRE_JOB_ESSENTIAL);
if (r) {
- ERROR(build->pakfire, "Could not add '%s' to the request: %m\n", requires);
+ ERROR(build->pakfire, "Could not add '%s' to the transaction: %m\n", requires);
goto ERROR;
}
// Solve the request
- r = pakfire_request_solve(request, 0);
+ r = pakfire_transaction_solve(transaction, 0, &problems);
if (r) {
- ERROR(build->pakfire, "Could not solve the request\n");
- goto ERROR;
- }
-
- // Fetch the transaction
- r = pakfire_request_get_transaction(request, &transaction);
- if (r) {
- ERROR(build->pakfire, "Could not fetch the transaction: %m\n");
+ ERROR(build->pakfire, "Could not solve the request:\n%s\n", problems);
goto ERROR;
}
goto ERROR;
ERROR:
- if (request)
- pakfire_request_unref(request);
if (transaction)
pakfire_transaction_unref(transaction);
+ if (problems)
+ free(problems);
return r;
}
static int pakfire_build_collect_packages(struct pakfire_build* build, const char* path) {
- struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
+ char* problems = NULL;
char* p = NULL;
int r;
- // Create a new request
- r = pakfire_request_create(&request, build->pakfire, 0);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, build->pakfire, 0);
if (r) {
- ERROR(build->pakfire, "Could not create request: %m\n");
+ ERROR(build->pakfire, "Could not create transaction: %m\n");
goto ERROR;
}
// XXX
// Install the base system
- r = pakfire_request_add(request, PAKFIRE_REQ_INSTALL, "ipfire-release",
- PAKFIRE_REQUEST_ESSENTIAL);
+ r = pakfire_transaction_request(transaction,
+ PAKFIRE_JOB_INSTALL, "ipfire-release", PAKFIRE_JOB_ESSENTIAL);
if (r) {
ERROR(build->pakfire, "Could not install 'ipfire-release': %m\n");
goto ERROR;
}
- // Solve the request
- r = pakfire_request_solve(request, 0);
- if (r) {
- ERROR(build->pakfire, "Could not solve request\n");
- goto ERROR;
- }
-
- // Get the transaction
- r = pakfire_request_get_transaction(request, &transaction);
+ // Solve the transaction
+ r = pakfire_transaction_solve(transaction, 0, &problems);
if (r) {
- ERROR(build->pakfire, "Could not fetch transaction: %m\n");
+ ERROR(build->pakfire, "Could not solve request:\n%s\n", problems);
goto ERROR;
}
ERROR:
if (transaction)
pakfire_transaction_unref(transaction);
- if (request)
- pakfire_request_unref(request);
+ if (problems)
+ free(problems);
if (p)
free(p);
};
// Installcheck
-int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem);
+int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem, int flags);
#ifdef PAKFIRE_PRIVATE
const char* pakfire_problem_to_string(struct pakfire_problem* problem);
-struct pakfire_request* pakfire_problem_get_request(struct pakfire_problem* problem);
-
int pakfire_problem_next_solution(
struct pakfire_problem* problem, struct pakfire_solution** solution);
#ifdef PAKFIRE_PRIVATE
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
int pakfire_problem_create(struct pakfire_problem** problem, struct pakfire* pakfire,
- struct pakfire_request* request, Id id);
+ struct pakfire_transaction* transaction, Id id);
+
+struct pakfire_transaction* pakfire_problem_get_transaction(struct pakfire_problem* problem);
struct pakfire* pakfire_problem_get_pakfire(struct pakfire_problem* problem);
Id pakfire_problem_get_id(struct pakfire_problem* problem);
+++ /dev/null
-/*#############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2013 Pakfire development team #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-# #
-#############################################################################*/
-
-#ifndef PAKFIRE_REQUEST_H
-#define PAKFIRE_REQUEST_H
-
-enum pakfire_request_flags {
- PAKFIRE_REQUEST_WITHOUT_RECOMMENDED = 1 << 0,
- PAKFIRE_REQUEST_ALLOW_UNINSTALL = 1 << 1,
- PAKFIRE_REQUEST_ALLOW_DOWNGRADE = 1 << 2,
-};
-
-enum pakfire_request_job_flags {
- PAKFIRE_REQUEST_KEEP_DEPS = 1 << 0,
- PAKFIRE_REQUEST_KEEP_ORPHANED = 1 << 1,
- PAKFIRE_REQUEST_ESSENTIAL = 1 << 2,
-};
-
-#ifdef PAKFIRE_PRIVATE
-
-#include <solv/solver.h>
-
-#include <pakfire/package.h>
-#include <pakfire/problem.h>
-#include <pakfire/solution.h>
-#include <pakfire/transaction.h>
-
-struct pakfire_request;
-
-enum pakfire_request_action {
- PAKFIRE_REQ_INSTALL,
- PAKFIRE_REQ_ERASE,
- PAKFIRE_REQ_UPDATE,
- PAKFIRE_REQ_UPDATE_ALL,
- PAKFIRE_REQ_SYNC,
- PAKFIRE_REQ_LOCK,
- PAKFIRE_REQ_VERIFY,
-};
-
-enum pakfire_request_solve_flags {
- PAKFIRE_REQ_SOLVE_INTERACTIVE,
-};
-
-int pakfire_request_create(struct pakfire_request** request, struct pakfire* pakfire, int flags);
-
-struct pakfire_request* pakfire_request_ref(struct pakfire_request* request);
-struct pakfire_request* pakfire_request_unref(struct pakfire_request* request);
-
-int pakfire_request_solve(struct pakfire_request* request, int flags);
-
-int pakfire_request_add(struct pakfire_request* request,
- const enum pakfire_request_action action, const char* what, int flags);
-int pakfire_request_add_package(struct pakfire_request* request,
- const enum pakfire_request_action action, struct pakfire_package* package, int flags);
-
-int pakfire_request_take_solution(struct pakfire_request* request,
- struct pakfire_solution* solution);
-
-Solver* pakfire_request_get_solver(struct pakfire_request* request);
-
-char* pakfire_request_get_problem_string(struct pakfire_request* request);
-
-int pakfire_request_next_problem(
- struct pakfire_request* request, struct pakfire_problem** problem);
-
-int pakfire_request_get_transaction(struct pakfire_request* request,
- struct pakfire_transaction** transaction);
-
-#endif
-
-#endif /* PAKFIRE_REQUEST_H */
struct pakfire_transaction;
+#include <pakfire/pakfire.h>
+#include <pakfire/problem.h>
+
enum pakfire_transaction_flags {
- PAKFIRE_TRANSACTION_DRY_RUN = (1 << 0),
+ // XXX DRY_RUN has to be removed
+ PAKFIRE_TRANSACTION_DRY_RUN = 1 << 0,
+ PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED = 1 << 1,
+ PAKFIRE_TRANSACTION_ALLOW_UNINSTALL = 1 << 2,
+ PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE = 1 << 3,
+};
+
+enum pakfire_job_action {
+ PAKFIRE_JOB_INSTALL,
+ PAKFIRE_JOB_ERASE,
+ PAKFIRE_JOB_UPDATE,
+ PAKFIRE_JOB_UPDATE_ALL,
+ PAKFIRE_JOB_SYNC,
+ PAKFIRE_JOB_LOCK,
+ PAKFIRE_JOB_VERIFY,
+};
+
+enum pakfire_job_flags {
+ PAKFIRE_JOB_KEEP_DEPS = 1 << 0,
+ PAKFIRE_JOB_KEEP_ORPHANED = 1 << 1,
+ PAKFIRE_JOB_ESSENTIAL = 1 << 2,
+ PAKFIRE_JOB_BEST = 1 << 3,
};
+int pakfire_transaction_create(struct pakfire_transaction** transaction,
+ struct pakfire* pakfire, int flags);
+
struct pakfire_transaction* pakfire_transaction_ref(struct pakfire_transaction* transaction);
struct pakfire_transaction* pakfire_transaction_unref(struct pakfire_transaction* transaction);
+// Callbacks
+void pakfire_transaction_set_status_callback(
+ struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data);
+
+int pakfire_transaction_solve(struct pakfire_transaction* transaction, int flags, char** problems);
+
+int pakfire_transaction_request(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, const char* what, int flags);
+int pakfire_transaction_request_package(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, struct pakfire_package* package, int flags);
+
size_t pakfire_transaction_count(struct pakfire_transaction* transaction);
char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t width);
#include <solv/solver.h>
#include <pakfire/key.h>
+#include <pakfire/solution.h>
-int pakfire_transaction_create(struct pakfire_transaction** transaction,
- struct pakfire* pakfire, Solver* solver);
+// XXX needs removal
+enum pakfire_request_solve_flags {
+ PAKFIRE_REQ_SOLVE_INTERACTIVE,
+};
+
+Solver* pakfire_transaction_get_solver(struct pakfire_transaction* transaction);
+
+int pakfire_transaction_next_problem(
+ struct pakfire_transaction* transaction, struct pakfire_problem** problem);
+
+int pakfire_transaction_take_solution(struct pakfire_transaction* transaction,
+ struct pakfire_solution* solution);
int pakfire_transaction_compose_repo(struct pakfire_transaction* transaction,
struct pakfire_key* key, const char* path);
#ifdef PAKFIRE_PRIVATE
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request);
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_transaction* transaction);
#endif
pakfire_transaction_download;
pakfire_transaction_dump;
pakfire_transaction_ref;
+ pakfire_transaction_request;
+ pakfire_transaction_request_package;
pakfire_transaction_run;
+ pakfire_transaction_set_status_callback;
pakfire_transaction_unref;
local:
#include <pakfire/pakfire.h>
#include <pakfire/private.h>
#include <pakfire/repo.h>
-#include <pakfire/request.h>
#include <pakfire/string.h>
+#include <pakfire/transaction.h>
#include <pakfire/util.h>
struct pakfire_package {
return md;
}
-PAKFIRE_EXPORT int pakfire_package_installcheck(struct pakfire_package* pkg, char** problem) {
- struct pakfire_request* request = NULL;
+PAKFIRE_EXPORT int pakfire_package_installcheck(struct pakfire_package* pkg,
+ char** problem, int flags) {
+ struct pakfire_transaction* transaction = NULL;
+ char* p = NULL;
int r;
const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
- // Create a new request
- r = pakfire_request_create(&request, pkg->pakfire, 0);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, pkg->pakfire, flags);
if (r)
goto ERROR;
// Install the package
- r = pakfire_request_add_package(request, PAKFIRE_REQ_INSTALL, pkg, 0);
+ r = pakfire_transaction_request_package(transaction,
+ PAKFIRE_JOB_INSTALL, pkg, PAKFIRE_JOB_ESSENTIAL);
if (r) {
ERROR(pkg->pakfire, "Could not add package %s to the request\n", nevra);
goto ERROR;
}
- // Solve the request
- r = pakfire_request_solve(request, 0);
+ // Solve the transaction
+ r = pakfire_transaction_solve(transaction, 0, &p);
if (r) {
- DEBUG(pkg->pakfire, "Could not install %s:\n", nevra);
+ DEBUG(pkg->pakfire, "Could not install %s:\n%s\n", nevra, p);
- // Fetch the problem
- *problem = pakfire_request_get_problem_string(request);
- if (*problem)
- DEBUG(pkg->pakfire, "%s\n", *problem);
+ // Copy the problem string
+ if (p)
+ *problem = strdup(p);
}
ERROR:
- if (request)
- pakfire_request_unref(request);
+ if (p)
+ free(p);
+ if (transaction)
+ pakfire_transaction_unref(transaction);
return r;
}
#include <pakfire/private.h>
#include <pakfire/pwd.h>
#include <pakfire/repo.h>
-#include <pakfire/request.h>
#include <pakfire/string.h>
#include <pakfire/transaction.h>
#include <pakfire/ui.h>
struct pakfire* pakfire,
int transaction_flags,
int solver_flags,
- const enum pakfire_request_action action,
+ const enum pakfire_job_action action,
const char** packages,
const char** locks,
int job_flags,
int* changed,
pakfire_status_callback status_callback,
void* status_callback_data) {
- struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
int r = 1;
if (r)
goto ERROR;
- // Create a new request
- r = pakfire_request_create(&request, pakfire, solver_flags);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, pakfire, solver_flags);
if (r)
goto ERROR;
+ // Set status callback
+ if (status_callback)
+ pakfire_transaction_set_status_callback(
+ transaction, status_callback, status_callback_data);
+
// Lock anything that should be locked
if (locks) {
for (const char** lock = locks; *lock; lock++) {
- r = pakfire_request_add(request, PAKFIRE_REQ_LOCK, *lock, 0);
+ r = pakfire_transaction_request(transaction, PAKFIRE_JOB_LOCK, *lock, 0);
if (r) {
ERROR(pakfire, "Could not lock '%s': %m\n", *lock);
goto ERROR;
// Perform action on all packages
for (const char** package = packages; *package; package++) {
- r = pakfire_request_add(request, action, *package, job_flags);
+ r = pakfire_transaction_request(transaction, action, *package, job_flags);
if (r) {
ERROR(pakfire, "Could not find '%s': %m\n", *package);
goto ERROR;
}
}
- // Solve the request
- r = pakfire_request_solve(request, PAKFIRE_REQ_SOLVE_INTERACTIVE);
- if (r)
- goto ERROR;
-
- // Fetch the transaction
- r = pakfire_request_get_transaction(request, &transaction);
+ // Solve the transaction
+ r = pakfire_transaction_solve(transaction, PAKFIRE_REQ_SOLVE_INTERACTIVE, NULL);
if (r)
goto ERROR;
if (changed)
*changed = pakfire_transaction_count(transaction);
- // Set status callback
- if (status_callback)
- pakfire_transaction_set_status_callback(
- transaction, status_callback, status_callback_data);
-
// Run the transaction
r = pakfire_transaction_run(transaction, transaction_flags);
if (r)
if (transaction)
pakfire_transaction_unref(transaction);
- if (request)
- pakfire_request_unref(request);
return r;
}
pakfire,
transaction_flags,
solver_flags,
- PAKFIRE_REQ_INSTALL,
+ PAKFIRE_JOB_INSTALL,
packages,
locks,
flags,
pakfire,
transaction_flags,
solver_flags,
- PAKFIRE_REQ_ERASE,
+ PAKFIRE_JOB_ERASE,
packages,
locks,
flags,
}
static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solver_flags,
- const enum pakfire_request_action action, int job_flags, int* changed,
+ const enum pakfire_job_action action, int job_flags, int* changed,
pakfire_status_callback status_callback, void* status_callback_data) {
- struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
int r = 1;
if (r)
goto ERROR;
- // Create a new request
- r = pakfire_request_create(&request, pakfire, solver_flags);
+ // Create a new transaction
+ r = pakfire_transaction_create(&transaction, pakfire, solver_flags);
if (r)
goto ERROR;
- // Perform action
- r = pakfire_request_add(request, action, NULL, job_flags);
- if (r)
- goto ERROR;
+ // Set status callback
+ if (status_callback)
+ pakfire_transaction_set_status_callback(
+ transaction, status_callback, status_callback_data);
- // Solve the request
- r = pakfire_request_solve(request, PAKFIRE_REQ_SOLVE_INTERACTIVE);
+ // Perform action
+ r = pakfire_transaction_request(transaction, action, NULL, job_flags);
if (r)
goto ERROR;
- // Fetch the transaction
- r = pakfire_request_get_transaction(request, &transaction);
+ // Solve the transaction
+ r = pakfire_transaction_solve(transaction, PAKFIRE_REQ_SOLVE_INTERACTIVE, NULL);
if (r)
goto ERROR;
if (changed)
*changed = pakfire_transaction_count(transaction);
- // Set status callback
- if (status_callback)
- pakfire_transaction_set_status_callback(
- transaction, status_callback, status_callback_data);
-
// Run the transaction
r = pakfire_transaction_run(transaction, 0);
if (r)
if (transaction)
pakfire_transaction_unref(transaction);
- if (request)
- pakfire_request_unref(request);
return r;
}
// XXX add locks
if (!packages)
return pakfire_perform_transaction_simple(
- pakfire, solver_flags, PAKFIRE_REQ_UPDATE_ALL, flags, changed,
+ pakfire, solver_flags, PAKFIRE_JOB_UPDATE_ALL, flags, changed,
status_callback, status_callback_data);
return pakfire_perform_transaction(pakfire, transaction_flags, solver_flags,
- PAKFIRE_REQ_UPDATE, packages, locks, flags, changed,
+ PAKFIRE_JOB_UPDATE, packages, locks, flags, changed,
status_callback, status_callback_data);
}
static int pakfire_verify(struct pakfire* pakfire, int *changed) {
- return pakfire_perform_transaction_simple(pakfire, 0, PAKFIRE_REQ_VERIFY,
+ return pakfire_perform_transaction_simple(pakfire, 0, PAKFIRE_JOB_VERIFY,
0, changed, NULL, NULL);
}
PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags,
int* changed, pakfire_status_callback status_callback, void* status_callback_data) {
return pakfire_perform_transaction_simple(pakfire, solver_flags,
- PAKFIRE_REQ_SYNC, flags, changed, status_callback, status_callback_data);
+ PAKFIRE_JOB_SYNC, flags, changed, status_callback, status_callback_data);
}
#include <pakfire/pakfire.h>
#include <pakfire/private.h>
#include <pakfire/problem.h>
-#include <pakfire/request.h>
#include <pakfire/solution.h>
+#include <pakfire/transaction.h>
#include <pakfire/util.h>
struct pakfire_problem {
struct pakfire* pakfire;
int nrefs;
- struct pakfire_request* request;
+ struct pakfire_transaction* transaction;
Id id;
char* string;
};
static char* pakfire_problem_make_string(struct pakfire_problem* problem) {
- Solver* solver = pakfire_request_get_solver(problem->request);
+ Solver* solver = pakfire_transaction_get_solver(problem->transaction);
Pool* pool = solver->pool;
// Get the problem rule
return s;
}
-PAKFIRE_EXPORT int pakfire_problem_create(struct pakfire_problem** problem,
- struct pakfire* pakfire, struct pakfire_request* request, Id id) {
+int pakfire_problem_create(struct pakfire_problem** problem,
+ struct pakfire* pakfire, struct pakfire_transaction* transaction, Id id) {
struct pakfire_problem* p = calloc(1, sizeof(*p));
if (!p)
return 1;
p->pakfire = pakfire_ref(pakfire);
p->nrefs = 1;
- p->request = pakfire_request_ref(request);
+ p->transaction = pakfire_transaction_ref(transaction);
p->id = id;
*problem = p;
}
static void pakfire_problem_free(struct pakfire_problem* problem) {
- pakfire_request_unref(problem->request);
-
+ if (problem->transaction)
+ pakfire_transaction_unref(problem->transaction);
if (problem->string)
free(problem->string);
-
pakfire_unref(problem->pakfire);
free(problem);
}
return problem->id;
}
-PAKFIRE_EXPORT struct pakfire_request* pakfire_problem_get_request(struct pakfire_problem* problem) {
- return pakfire_request_ref(problem->request);
+struct pakfire_transaction* pakfire_problem_get_transaction(struct pakfire_problem* problem) {
+ return pakfire_transaction_ref(problem->transaction);
}
PAKFIRE_EXPORT int pakfire_problem_next_solution(
struct pakfire_problem* problem, struct pakfire_solution** solution) {
- Solver* solver = pakfire_request_get_solver(problem->request);
+ Solver* solver = pakfire_transaction_get_solver(problem->transaction);
Id id = 0;
// Check input
+++ /dev/null
-/*#############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2013 Pakfire development team #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program is distributed in the hope that it will be useful, #
-# but WITHOUT ANY WARRANTY; without even the implied warranty of #
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
-# GNU General Public License for more details. #
-# #
-# You should have received a copy of the GNU General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-# #
-#############################################################################*/
-
-#include <ctype.h>
-#include <errno.h>
-#include <linux/limits.h>
-#include <stdlib.h>
-
-#include <solv/queue.h>
-#include <solv/selection.h>
-#include <solv/solver.h>
-#include <solv/transaction.h>
-
-#ifdef ENABLE_DEBUG
-# include <solv/solverdebug.h>
-#endif
-
-#include <pakfire/archive.h>
-#include <pakfire/dependencies.h>
-#include <pakfire/logging.h>
-#include <pakfire/package.h>
-#include <pakfire/pakfire.h>
-#include <pakfire/problem.h>
-#include <pakfire/request.h>
-#include <pakfire/string.h>
-#include <pakfire/transaction.h>
-#include <pakfire/ui.h>
-#include <pakfire/util.h>
-
-struct pakfire_request {
- struct pakfire* pakfire;
- int nrefs;
-
- Solver* solver;
- Queue jobs;
-};
-
-static void pakfire_request_free(struct pakfire_request* request) {
- if (request->solver)
- solver_free(request->solver);
- queue_free(&request->jobs);
-
- pakfire_unref(request->pakfire);
- free(request);
-}
-
-static int setup_solver(struct pakfire_request* request, int flags) {
- // Obey policy when searching for the best solvable
- solver_set_flag(request->solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
-
- // Automatically update when installation is requested
- solver_set_flag(request->solver, SOLVER_FLAG_INSTALL_ALSO_UPDATES, 1);
-
- // Can the solver downgrade packages?
- if (flags & PAKFIRE_REQUEST_ALLOW_DOWNGRADE)
- solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
-
- // Can the solver uninstall packages?
- if (flags & PAKFIRE_REQUEST_ALLOW_UNINSTALL)
- solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
-
- // Do not install any recommended packages
- if (flags & PAKFIRE_REQUEST_WITHOUT_RECOMMENDED)
- solver_set_flag(request->solver, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
-
- return 0;
-}
-
-int pakfire_request_create(struct pakfire_request** request,
- struct pakfire* pakfire, int flags) {
- Pool* pool = pakfire_get_solv_pool(pakfire);
- int r = 1;
-
- // Cannot create a solver when no installed repository has been set
- if (!pool->installed)
- return -EINVAL;
-
- // Allocate request
- struct pakfire_request* req = calloc(1, sizeof(*req));
- if (!req)
- return ENOMEM;
-
- req->pakfire = pakfire_ref(pakfire);
- req->nrefs = 1;
-
- // Allocate a job queue
- queue_init(&req->jobs);
-
- // Allocate solver
- req->solver = solver_create(pool);
- if (!req->solver) {
- ERROR(pakfire, "Could not allocate solver: %m\n");
- goto ERROR;
- }
-
- // Set up solver
- r = setup_solver(req, flags);
- if (r)
- goto ERROR;
-
- *request = req;
- return 0;
-
-ERROR:
- pakfire_request_free(req);
- return r;
-}
-
-struct pakfire_request* pakfire_request_ref(struct pakfire_request* request) {
- request->nrefs++;
-
- return request;
-}
-
-struct pakfire_request* pakfire_request_unref(struct pakfire_request* request) {
- if (--request->nrefs > 0)
- return request;
-
- pakfire_request_free(request);
- return NULL;
-}
-
-Solver* pakfire_request_get_solver(struct pakfire_request* request) {
- return request->solver;
-}
-
-static int pakfire_request_pick_solution(struct pakfire_request* request) {
- // XXX TODO this is just a dummy
- return pakfire_ui_pick_solution(request->pakfire, request);
-}
-
-int pakfire_request_solve(struct pakfire_request* request, int flags) {
- int solved = 0;
- int r;
-
- // Prepare pool
- pakfire_pool_internalize(request->pakfire);
-
-#ifdef ENABLE_DEBUG
- Pool* pool = pakfire_get_solv_pool(request->pakfire);
-
- const char* selection = pool_selection2str(pool, &request->jobs, 0);
- if (selection) {
- DEBUG(request->pakfire, "Solving: %s\n", selection);
- }
-#endif
-
- // Save time when we starting solving
- clock_t solving_start = clock();
-
-RETRY:
- r = solver_solve(request->solver, &request->jobs);
- switch (r) {
- // Solved!
- case 0:
- // Mark as solved
- solved = 1;
- break;
-
- // Not Solved
- default:
-#ifdef ENABLE_DEBUG
- // Print all solutions
- solver_printallsolutions(request->solver);
-#endif
-
- // Ask the user to pick a solution
- if (flags & PAKFIRE_REQ_SOLVE_INTERACTIVE) {
- r = pakfire_request_pick_solution(request);
- if (r)
- return r;
-
- // Retry solving
- goto RETRY;
-
- } else {
- char* s = pakfire_request_get_problem_string(request);
- if (s)
- ERROR(request->pakfire, "%s\n", s);
- }
- break;
- }
-
- // Save time when we finished solving
- clock_t solving_end = clock();
-
- DEBUG(request->pakfire, "Solved request in %.4fms\n",
- (double)(solving_end - solving_start) * 1000 / CLOCKS_PER_SEC);
-
-#ifdef ENABLE_DEBUG
- if (solved)
- solver_printdecisions(request->solver);
-#endif
-
- // Return zero if solved, otherwise return non-zero
- if (solved)
- return 0;
-
- return 2;
-}
-
-static int pakfire_request_is_file(const char* what) {
- return pakfire_string_endswith(what, ".pfm");
-}
-
-static int __pakfire_request_add(struct pakfire_request* request,
- const enum pakfire_request_action action, const Id type, const Id id, int flags) {
- Id job = ID_NULL;
-
- // Check if type/ID is not set for actions that don't support it
- switch (action) {
- case PAKFIRE_REQ_INSTALL:
- case PAKFIRE_REQ_ERASE:
- case PAKFIRE_REQ_UPDATE:
- case PAKFIRE_REQ_LOCK:
- break;
-
- default:
- if (type || id) {
- errno = EINVAL;
- return 1;
- }
- }
-
- // Essential jobs
- if (flags & PAKFIRE_REQUEST_ESSENTIAL)
- job |= SOLVER_ESSENTIAL;
-
- // Select the correct action
- switch (action) {
- case PAKFIRE_REQ_INSTALL:
- job |= SOLVER_INSTALL;
- break;
-
- case PAKFIRE_REQ_ERASE:
- job |= SOLVER_ERASE;
-
- // Should we keep any dependencies?
- if (!(flags & PAKFIRE_REQUEST_KEEP_DEPS))
- job |= SOLVER_CLEANDEPS;
- break;
-
- case PAKFIRE_REQ_UPDATE:
- job |= SOLVER_UPDATE;
- break;
-
- case PAKFIRE_REQ_UPDATE_ALL:
- job |= SOLVER_UPDATE|SOLVER_SOLVABLE_ALL;
- break;
-
- case PAKFIRE_REQ_SYNC:
- job |= SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL;
-
- // Drop orphans?
- if (!(flags & PAKFIRE_REQUEST_KEEP_ORPHANED))
- queue_push2(&request->jobs, SOLVER_DROP_ORPHANED, 0);
- break;
-
- case PAKFIRE_REQ_LOCK:
- job |= SOLVER_LOCK;
- break;
-
- case PAKFIRE_REQ_VERIFY:
- job |= SOLVER_VERIFY|SOLVER_SOLVABLE_ALL;
- break;
- }
-
- // Add it to the job queue
- queue_push2(&request->jobs, job|type, id);
-
- return 0;
-}
-
-static int pakfire_request_add_job(struct pakfire_request* request,
- const enum pakfire_request_action action, const char* what, int extra_flags) {
- Pool* pool = pakfire_get_solv_pool(request->pakfire);
-
- // Make the pool ready
- pakfire_pool_internalize(request->pakfire);
-
- Queue jobs;
- queue_init(&jobs);
-
- int flags =
- // Select packages by name
- SELECTION_NAME|
- // Select packages by what they provide
- SELECTION_PROVIDES|
- // Process globbing patterns
- SELECTION_GLOB|
- // Select packages by their canonical name
- SELECTION_CANON|
- // Process .arch
- SELECTION_DOTARCH|
- // Process -release
- SELECTION_REL;
-
- // Process filelists?
- if (*what == '/')
- flags |= SELECTION_FILELIST;
-
- // Select all packages
- selection_make(pool, &jobs, what, flags);
-
- // Did we find anything?
- if (jobs.count == 0) {
- Id id = pakfire_str2dep(request->pakfire, what);
- if (!id)
- return 1;
-
- queue_push2(&jobs, SOLVER_SOLVABLE_PROVIDES, id);
- }
-
- DEBUG(request->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what);
-
- // Set action and global flags
- for (int i = 0; i < jobs.count; i += 2)
- __pakfire_request_add(request, action, jobs.elements[i], jobs.elements[i+1], extra_flags);
-
- queue_free(&jobs);
-
- return 0;
-}
-
-int pakfire_request_add(struct pakfire_request* request,
- const enum pakfire_request_action action, const char* what, int flags) {
- struct pakfire_package* package = NULL;
- int r;
-
- // Remove leading whitespace
- if (what) {
- while (*what && isspace(*what))
- what++;
- }
-
- if (!what) {
- r = __pakfire_request_add(request, action, ID_NULL, ID_NULL, flags);
- if (r)
- goto ERROR;
-
- // Check if we got given a URL or some file
- } else if (pakfire_string_is_url(what) || pakfire_request_is_file(what)) {
- // Add them to the commandline repository
- r = pakfire_commandline_add(request->pakfire, what, &package);
- if (r)
- goto ERROR;
-
- // Then add the package
- r = pakfire_request_add_package(request, action, package, flags);
- if (r)
- goto ERROR;
-
- // Otherwise try adding this as a job
- } else {
- r = pakfire_request_add_job(request, action, what, flags);
- if (r)
- goto ERROR;
- }
-
-ERROR:
- if (package)
- pakfire_package_unref(package);
-
- return r;
-}
-
-int pakfire_request_add_package(struct pakfire_request* request,
- const enum pakfire_request_action action, struct pakfire_package* package, int flags) {
- // Get the solvable ID
- Id id = pakfire_package_id(package);
-
- // Add it to the job queue
- return __pakfire_request_add(request, action, SOLVER_SOLVABLE, id, flags);
-}
-
-char* pakfire_request_get_problem_string(struct pakfire_request* request) {
- struct pakfire_problem* problem = NULL;
- char* s = NULL;
- int r;
-
- for (;;) {
- r = pakfire_request_next_problem(request, &problem);
- if (r || !problem)
- break;
-
- const char* p = pakfire_problem_to_string(problem);
-
- r = asprintf(&s, "%s%s\n", (s) ? s : "", p);
- if (r < 0)
- return NULL;
- }
-
- return s;
-}
-
-int pakfire_request_next_problem(
- struct pakfire_request* request, struct pakfire_problem** problem) {
- Id id = 0;
-
- // Check input
- if (!problem) {
- errno = EINVAL;
- return 1;
- }
-
- // Fetch the ID of the previous problem
- if (*problem) {
- id = pakfire_problem_get_id(*problem);
-
- // Free the previous problem
- pakfire_problem_unref(*problem);
- *problem = NULL;
- }
-
- // Fetch the ID of the next problem
- id = solver_next_problem(request->solver, id);
- if (!id)
- return 0;
-
- // Create problem
- return pakfire_problem_create(problem, request->pakfire, request, id);
-}
-
-int pakfire_request_take_solution(struct pakfire_request* request,
- struct pakfire_solution* solution) {
- struct pakfire_problem* problem = pakfire_solution_get_problem(solution);
-
- // Fetch IDs
- Id problem_id = pakfire_problem_get_id(problem);
- Id solution_id = pakfire_solution_get_id(solution);
-
- // Feed the solution into the solver
- solver_take_solution(request->solver, problem_id, solution_id, &request->jobs);
-
- pakfire_problem_unref(problem);
- return 0;
-}
-
-int pakfire_request_get_transaction(struct pakfire_request* request,
- struct pakfire_transaction** transaction) {
- // XXX Check if we have solved successfully
-
- // Create the transaction
- return pakfire_transaction_create(transaction, request->pakfire, request->solver);
-}
#include <pakfire/logging.h>
#include <pakfire/private.h>
#include <pakfire/problem.h>
-#include <pakfire/request.h>
#include <pakfire/solution.h>
#include <pakfire/string.h>
+#include <pakfire/transaction.h>
#include <pakfire/util.h>
struct pakfire_solution {
}
static char* pakfire_solution_make_string(struct pakfire_solution* solution) {
- struct pakfire_request* request = pakfire_problem_get_request(solution->problem);
- Solver* solver = pakfire_request_get_solver(request);
+ struct pakfire_transaction* transaction = pakfire_problem_get_transaction(solution->problem);
+ Solver* solver = pakfire_transaction_get_solver(transaction);
Pool* pool = solver->pool;
// Fetch the problem ID
// How many elements do we have?
unsigned int count = solver_solutionelement_count(solver, problem_id, solution->id);
if (!count) {
- pakfire_request_unref(request);
+ pakfire_transaction_unref(transaction);
return NULL;
}
s = pakfire_string_join(elements, "\n");
ERROR:
- pakfire_request_unref(request);
+ if (transaction)
+ pakfire_transaction_unref(transaction);
// Free all elements
for (char** element = elements; *element; element++)
# #
#############################################################################*/
+#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
+#include <solv/selection.h>
#include <solv/transaction.h>
#include <solv/solverdebug.h>
#include <pakfire/archive.h>
#include <pakfire/db.h>
+#include <pakfire/dependencies.h>
#include <pakfire/digest.h>
#include <pakfire/downloader.h>
#include <pakfire/file.h>
struct pakfire* pakfire;
int nrefs;
+ // Flags
+ int flags;
+
+ // The solver
+ Solver* solver;
+ enum pakfire_transaction_solver_status {
+ SOLVER_STATUS_UNKNOWN,
+ } solver_status;
+
+ // The jobs to solve
+ Queue jobs;
+
Transaction* transaction;
char** userinstalled;
free(*userinstalled);
free(transaction->userinstalled);
}
- transaction_free(transaction->transaction);
+ if (transaction->transaction)
+ transaction_free(transaction->transaction);
+
+ if (transaction->solver)
+ solver_free(transaction->solver);
pakfire_unref(transaction->pakfire);
free(transaction);
}
-static int pakfire_transaction_import_transaction(
- struct pakfire_transaction* transaction, Solver* solver) {
+static int pakfire_transaction_import_transaction(struct pakfire_transaction* transaction) {
int r;
// Clone the transaction to keep a copy of it
- Transaction* t = solver_create_transaction(solver);
- if (!t)
+ transaction->transaction = solver_create_transaction(transaction->solver);
+ if (!transaction->transaction) {
+ ERROR(transaction->pakfire, "Could not create transaction from solver: %m\n");
return 1;
-
- transaction->transaction = t;
+ }
// Order the transaction
- transaction_order(t, 0);
+ transaction_order(transaction->transaction, 0);
// Log the transaction
- transaction_print(t);
+ transaction_print(transaction->transaction);
// Free any previous content
pakfire_transaction_free_archives_and_packages(transaction);
// How many steps?
- transaction->num = t->steps.count;
+ transaction->num = transaction->transaction->steps.count;
// Allocate space for packages
transaction->packages = calloc(transaction->num, sizeof(*transaction->packages));
// Create all packages
for (unsigned int i = 0; i < transaction->num; i++) {
r = pakfire_package_create_from_solvable(&transaction->packages[i],
- transaction->pakfire, t->steps.elements[i]);
+ transaction->pakfire, transaction->transaction->steps.elements[i]);
if (r)
return r;
}
return 0;
}
-static int pakfire_transaction_import_userinstalled(
- struct pakfire_transaction* t, Solver* solver) {
+static int pakfire_transaction_import_userinstalled(struct pakfire_transaction* transaction) {
Queue userinstalled;
const char* package = NULL;
int r = 0;
queue_init(&userinstalled);
// Cleanup previous content
- if (t->userinstalled) {
- pakfire_strings_free(t->userinstalled);
- t->userinstalled = NULL;
+ if (transaction->userinstalled) {
+ pakfire_strings_free(transaction->userinstalled);
+ transaction->userinstalled = NULL;
}
// Fetch a list of all packages that are installed by the user
- solver_get_userinstalled(solver, &userinstalled, GET_USERINSTALLED_NAMES);
+ solver_get_userinstalled(transaction->solver, &userinstalled, GET_USERINSTALLED_NAMES);
// Skip everything if the queue is empty
if (!userinstalled.count)
goto OUT;
- t->userinstalled = calloc(userinstalled.count + 1, sizeof(*t->userinstalled));
- if (!t->userinstalled) {
- ERROR(t->pakfire, "Could not allocate userinstalled: %m\n");
+ transaction->userinstalled = calloc(userinstalled.count + 1, sizeof(*transaction->userinstalled));
+ if (!transaction->userinstalled) {
+ ERROR(transaction->pakfire, "Could not allocate userinstalled: %m\n");
r = -errno;
goto ERROR;
}
- Pool* pool = pakfire_get_solv_pool(t->pakfire);
+ Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
// Store the names of all userinstalled packages
for (int i = 0; i < userinstalled.count; i++) {
package = pool_id2str(pool, userinstalled.elements[i]);
- t->userinstalled[i] = strdup(package);
+ transaction->userinstalled[i] = strdup(package);
- if (!t->userinstalled[i]) {
+ if (!transaction->userinstalled[i]) {
r = -errno;
goto ERROR;
}
r = 0;
ERROR:
- if (t->userinstalled) {
- pakfire_strings_free(t->userinstalled);
- t->userinstalled = NULL;
+ if (transaction->userinstalled) {
+ pakfire_strings_free(transaction->userinstalled);
+ transaction->userinstalled = NULL;
}
OUT:
return r;
}
-int pakfire_transaction_create(struct pakfire_transaction** transaction,
- struct pakfire* pakfire, Solver* solver) {
+static void pakfire_transaction_default_status_callback(
+ struct pakfire* pakfire, void* data, int progress, const char* status) {
+ // XXX perform some default action...
+}
+
+static int pakfire_transaction_setup_solver(struct pakfire_transaction* transaction) {
+ Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+ // Allocate a new solver
+ transaction->solver = solver_create(pool);
+ if (!transaction->solver) {
+ ERROR(transaction->pakfire, "Could not allocate solver: %m\n");
+ return -errno;
+ }
+
+ // Obey policy when searching for the best solvable
+ solver_set_flag(transaction->solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
+
+ // Automatically update when installation is requested
+ solver_set_flag(transaction->solver, SOLVER_FLAG_INSTALL_ALSO_UPDATES, 1);
+
+ // Can the solver downgrade packages?
+ if (transaction->flags & PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE)
+ solver_set_flag(transaction->solver, SOLVER_FLAG_ALLOW_DOWNGRADE, 1);
+
+ // Can the solver uninstall packages?
+ if (transaction->flags & PAKFIRE_TRANSACTION_ALLOW_UNINSTALL)
+ solver_set_flag(transaction->solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
+
+ // Do not install any recommended packages
+ if (transaction->flags & PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED)
+ solver_set_flag(transaction->solver, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
+
+ return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_create(struct pakfire_transaction** transaction,
+ struct pakfire* pakfire, int flags) {
+ int r;
+
+ // Allocate the transaction
struct pakfire_transaction* t = calloc(1, sizeof(*t));
if (!t)
- return ENOMEM;
+ return -errno;
// Store reference to Pakfire
t->pakfire = pakfire_ref(pakfire);
// Initialize the reference counter
t->nrefs = 1;
- // Import transaction
- int r = pakfire_transaction_import_transaction(t, solver);
- if (r)
- goto ERROR;
+ // Store flags
+ t->flags = flags;
- // Import userinstalled
- r = pakfire_transaction_import_userinstalled(t, solver);
+ // Set the default status callback
+ t->callbacks.status = pakfire_transaction_default_status_callback;
+
+ // Setup the solver
+ r = pakfire_transaction_setup_solver(t);
if (r)
goto ERROR;
+ // Allocate a job queue
+ queue_init(&t->jobs);
+
+ // Return the transaction
*transaction = t;
+
return 0;
ERROR:
pakfire_transaction_free(t);
- return 1;
+ return r;
}
PAKFIRE_EXPORT struct pakfire_transaction* pakfire_transaction_ref(
return NULL;
}
-void pakfire_transaction_set_status_callback(struct pakfire_transaction* transaction,
- pakfire_status_callback callback, void* data) {
+PAKFIRE_EXPORT void pakfire_transaction_set_status_callback(
+ struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data) {
transaction->callbacks.status = callback;
transaction->callbacks.status_data = data;
}
free(buffer);
}
+static char* pakfire_transaction_get_problem_string(struct pakfire_transaction* transaction) {
+ struct pakfire_problem* problem = NULL;
+ const char* p = NULL;
+ char* s = NULL;
+ int r;
+
+ for (;;) {
+ r = pakfire_transaction_next_problem(transaction, &problem);
+ if (r || !problem)
+ break;
+
+ p = pakfire_problem_to_string(problem);
+ if (!p)
+ goto ERROR;
+
+ r = asprintf(&s, "%s%s\n", (s) ? s : "", p);
+ if (r < 0)
+ goto ERROR;
+ }
+
+ return s;
+
+ERROR:
+ if (s)
+ free(s);
+
+ return NULL;
+}
+
+Solver* pakfire_transaction_get_solver(struct pakfire_transaction* transaction) {
+ return transaction->solver;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_solve(struct pakfire_transaction* transaction,
+ int flags, char** problems) {
+ int solved = 0;
+ int r;
+
+ // XXX halt if the request has already been solved
+
+ // Prepare pool
+ pakfire_pool_internalize(transaction->pakfire);
+
+#ifdef ENABLE_DEBUG
+ Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+ const char* selection = pool_selection2str(pool, &transaction->jobs, 0);
+ if (selection)
+ DEBUG(transaction->pakfire, "Solving: %s\n", selection);
+#endif
+
+RETRY:
+ // Save time when we starting solving
+ clock_t solving_start = clock();
+
+ r = solver_solve(transaction->solver, &transaction->jobs);
+
+ // Save time when we finished solving
+ clock_t solving_end = clock();
+
+ DEBUG(transaction->pakfire, "Solved request in %.4fms\n",
+ (double)(solving_end - solving_start) * 1000 / CLOCKS_PER_SEC);
+
+ switch (r) {
+ // Solved!
+ case 0:
+ // Mark as solved
+ solved = 1;
+
+ // Import the transaction
+ r = pakfire_transaction_import_transaction(transaction);
+ if (r)
+ goto ERROR;
+
+ // Import userinstalled packages
+ r = pakfire_transaction_import_userinstalled(transaction);
+ if (r)
+ goto ERROR;
+
+ break;
+
+ // Not Solved
+ default:
+#ifdef ENABLE_DEBUG
+ // Print all solutions
+ solver_printallsolutions(transaction->solver);
+#endif
+
+ // Return the problems as string
+ if (problems)
+ *problems = pakfire_transaction_get_problem_string(transaction);
+
+ // Ask the user to pick a solution
+ if (flags & PAKFIRE_REQ_SOLVE_INTERACTIVE) {
+ r = pakfire_ui_pick_solution(transaction->pakfire, transaction);
+ if (r)
+ return r;
+
+ // Retry solving
+ goto RETRY;
+
+ } else {
+ char* s = pakfire_transaction_get_problem_string(transaction);
+ if (s)
+ ERROR(transaction->pakfire, "%s\n", s);
+ }
+ break;
+ }
+
+#ifdef ENABLE_DEBUG
+ if (solved)
+ solver_printdecisions(transaction->solver);
+#endif
+
+ // Return zero if solved, otherwise return non-zero
+ if (solved)
+ return 0;
+
+ return 2;
+
+ERROR:
+ return r;
+}
+
+static int pakfire_transaction_is_file(const char* what) {
+ return pakfire_string_endswith(what, ".pfm");
+}
+
+static int __pakfire_transaction_add(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, const Id type, const Id id, int flags) {
+ Id job = ID_NULL;
+
+ // Check if type/ID is not set for actions that don't support it
+ switch (action) {
+ case PAKFIRE_JOB_INSTALL:
+ case PAKFIRE_JOB_ERASE:
+ case PAKFIRE_JOB_UPDATE:
+ case PAKFIRE_JOB_LOCK:
+ break;
+
+ default:
+ if (type || id)
+ return -EINVAL;
+ }
+
+ // Essential jobs
+ if (flags & PAKFIRE_JOB_ESSENTIAL)
+ job |= SOLVER_ESSENTIAL;
+
+ // Install the best package only?
+ if (flags & PAKFIRE_JOB_BEST)
+ job |= SOLVER_FORCEBEST;
+
+ // Select the correct action
+ switch (action) {
+ case PAKFIRE_JOB_INSTALL:
+ job |= SOLVER_INSTALL;
+ break;
+
+ case PAKFIRE_JOB_ERASE:
+ job |= SOLVER_ERASE;
+
+ // Should we keep any dependencies?
+ if (!(flags & PAKFIRE_JOB_KEEP_DEPS))
+ job |= SOLVER_CLEANDEPS;
+ break;
+
+ case PAKFIRE_JOB_UPDATE:
+ job |= SOLVER_UPDATE;
+ break;
+
+ case PAKFIRE_JOB_UPDATE_ALL:
+ job |= SOLVER_UPDATE|SOLVER_SOLVABLE_ALL;
+ break;
+
+ case PAKFIRE_JOB_SYNC:
+ job |= SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL;
+
+ // Drop orphans?
+ if (!(flags & PAKFIRE_JOB_KEEP_ORPHANED))
+ queue_push2(&transaction->jobs, SOLVER_DROP_ORPHANED, 0);
+ break;
+
+ case PAKFIRE_JOB_LOCK:
+ job |= SOLVER_LOCK;
+ break;
+
+ case PAKFIRE_JOB_VERIFY:
+ job |= SOLVER_VERIFY|SOLVER_SOLVABLE_ALL;
+ break;
+ }
+
+ // Add it to the job queue
+ queue_push2(&transaction->jobs, job|type, id);
+
+ return 0;
+}
+
+static int pakfire_transaction_add_job(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, const char* what, int extra_flags) {
+ Queue jobs;
+ int r;
+
+ Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+ // Make the pool ready
+ pakfire_pool_internalize(transaction->pakfire);
+
+ // Initialize jobs
+ queue_init(&jobs);
+
+ int flags =
+ // Select packages by name
+ SELECTION_NAME|
+ // Select packages by what they provide
+ SELECTION_PROVIDES|
+ // Process globbing patterns
+ SELECTION_GLOB|
+ // Select packages by their canonical name
+ SELECTION_CANON|
+ // Process .arch
+ SELECTION_DOTARCH|
+ // Process -release
+ SELECTION_REL;
+
+ // Process filelists?
+ if (*what == '/')
+ flags |= SELECTION_FILELIST;
+
+ // Select all packages
+ selection_make(pool, &jobs, what, flags);
+
+ // Did we find anything?
+ if (jobs.count == 0) {
+ Id id = pakfire_str2dep(transaction->pakfire, what);
+ if (!id) {
+ r = -errno;
+ goto ERROR;
+ }
+
+ queue_push2(&jobs, SOLVER_SOLVABLE_PROVIDES, id);
+ }
+
+ DEBUG(transaction->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what);
+
+ // Set action and global flags
+ for (int i = 0; i < jobs.count; i += 2) {
+ r = __pakfire_transaction_add(transaction, action,
+ jobs.elements[i], jobs.elements[i+1], extra_flags);
+ if (r)
+ goto ERROR;
+ }
+
+ // Success
+ r = 0;
+
+ERROR:
+ queue_free(&jobs);
+
+ return r;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_request(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, const char* what, int flags) {
+ struct pakfire_package* package = NULL;
+ int r;
+
+ // Remove leading whitespace
+ if (what) {
+ while (*what && isspace(*what))
+ what++;
+ }
+
+ if (!what) {
+ r = __pakfire_transaction_add(transaction, action, ID_NULL, ID_NULL, flags);
+ if (r)
+ goto ERROR;
+
+ // Check if we got given a URL or some file
+ } else if (pakfire_string_is_url(what) || pakfire_transaction_is_file(what)) {
+ // Add them to the commandline repository
+ r = pakfire_commandline_add(transaction->pakfire, what, &package);
+ if (r)
+ goto ERROR;
+
+ // Then add the package
+ r = pakfire_transaction_request_package(transaction, action, package, flags);
+ if (r)
+ goto ERROR;
+
+ // Otherwise try adding this as a job
+ } else {
+ r = pakfire_transaction_add_job(transaction, action, what, flags);
+ if (r)
+ goto ERROR;
+ }
+
+ERROR:
+ if (package)
+ pakfire_package_unref(package);
+
+ return r;
+}
+
+PAKFIRE_EXPORT int pakfire_transaction_request_package(struct pakfire_transaction* transaction,
+ const enum pakfire_job_action action, struct pakfire_package* package, int flags) {
+ // Get the solvable ID
+ Id id = pakfire_package_id(package);
+
+ // Add it to the job queue
+ return __pakfire_transaction_add(transaction, action, SOLVER_SOLVABLE, id, flags);
+}
+
+int pakfire_transaction_next_problem(
+ struct pakfire_transaction* transaction, struct pakfire_problem** problem) {
+ Id id = 0;
+
+ // Check input
+ if (!problem) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ // Fetch the ID of the previous problem
+ if (*problem) {
+ id = pakfire_problem_get_id(*problem);
+
+ // Free the previous problem
+ pakfire_problem_unref(*problem);
+ *problem = NULL;
+ }
+
+ // Fetch the ID of the next problem
+ id = solver_next_problem(transaction->solver, id);
+ if (!id)
+ return 0;
+
+ // Create problem
+ return pakfire_problem_create(problem, transaction->pakfire, transaction, id);
+}
+
+int pakfire_transaction_take_solution(struct pakfire_transaction* transaction,
+ struct pakfire_solution* solution) {
+ struct pakfire_problem* problem = pakfire_solution_get_problem(solution);
+
+ // Fetch IDs
+ Id problem_id = pakfire_problem_get_id(problem);
+ Id solution_id = pakfire_solution_get_id(solution);
+
+ // Feed the solution into the solver
+ solver_take_solution(transaction->solver, problem_id, solution_id, &transaction->jobs);
+
+ pakfire_problem_unref(problem);
+ return 0;
+}
+
PAKFIRE_EXPORT size_t pakfire_transaction_count(struct pakfire_transaction* transaction) {
return transaction->num;
}
struct pakfire_transaction* transaction, int flags) {
int r;
+ // XXX automatically solve
+ // XXX automatically download
+
// Skip running an empty transaction
if (!transaction->num) {
DEBUG(transaction->pakfire, "Empty transaction. Skipping...\n");
#include <pakfire/i18n.h>
#include <pakfire/pakfire.h>
#include <pakfire/problem.h>
-#include <pakfire/request.h>
+#include <pakfire/transaction.h>
#include <pakfire/ui.h>
static int pakfire_ui_is_interactive(struct pakfire* pakfire) {
return list;
}
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request) {
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_transaction* transaction) {
struct pakfire_problem* problem = NULL;
struct pakfire_solution** solutions = NULL;
struct pakfire_solution* solution = NULL;
// Print all problems
for (;;) {
- r = pakfire_request_next_problem(request, &problem);
+ r = pakfire_transaction_next_problem(transaction, &problem);
if (r)
goto ERROR;
goto ERROR;
// Fetch selected solution into the solver
- r = pakfire_request_take_solution(request, solutions[choice - 1]);
+ r = pakfire_transaction_take_solution(transaction, solutions[choice - 1]);
if (r)
goto ERROR;