#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
-// Enable legacy logging
-#define PAKFIRE_LEGACY_LOGGING
-
#include <pakfire/build.h>
#include <pakfire/cgroup.h>
#include <pakfire/config.h>
// States
int init:1;
-
- // Callbacks
- struct pakfire_build_callbacks {
- // Log callback
- pakfire_build_log_callback log;
- void* log_data;
- } callbacks;
};
#define TEMPLATE \
"\n" \
"exit 0\n"
-/*
- Convenience macro to call the logger callback
-*/
-static int pakfire_build_log(struct pakfire_build* build, int priority, int error,
- const char* file, int line, const char* function, const char* format, ...) {
- char* buffer = NULL;
- va_list args;
- int r;
-
- // Don't log messages of a lower loglevel
- if (pakfire_ctx_get_log_level(build->ctx) < priority)
- return 0;
-
- // Format message
- va_start(args, format);
- r = vasprintf(&buffer, format, args);
- va_end(args);
-
- // Fail if we could not format the message
- if (r < 0)
- return r;
-
- // Send everything to the context logger
- pakfire_ctx_log(build->ctx, priority, file, line, function, "%s", buffer);
-
- // Call the build logger callback
- if (build->callbacks.log)
- r = build->callbacks.log(build, build->callbacks.log_data, priority, error,
- file, line, function, "%s", buffer);
- else
- r = 0;
-
- // Cleanup
- if (buffer)
- free(buffer);
-
- return r;
-}
-
-#define BUILD_LOG_ERRNO(build, priority, r, arg...) \
- pakfire_build_log(build, priority, r, __FILE__, __LINE__, __FUNCTION__, ## arg)
-#define BUILD_LOG(build, priority, arg...) BUILD_LOG_ERRNO(build, priority, 0, ## arg)
-
-#define BUILD_INFO_ERRNO(build, r, arg...) BUILD_LOG_ERRNO(build, LOG_INFO, r, ## arg)
-#define BUILD_ERROR_ERRNO(build, r, arg...) BUILD_LOG_ERRNO(build, LOG_ERR, r, ## arg)
-#define BUILD_DEBUG_ERRNO(build, r, arg...) BUILD_LOG_ERRNO(build, LOG_DEBUG, r, ## arg)
-
-#define BUILD_INFO(build, arg...) BUILD_INFO_ERRNO(build, 0, ## arg)
-#define BUILD_ERROR(build, arg...) BUILD_ERROR_ERRNO(build, 0, ## arg)
-#define BUILD_DEBUG(build, arg...) BUILD_DEBUG_ERRNO(build, 0, ## arg)
-
static int pakfire_build_has_flag(struct pakfire_build* build, int flag) {
return build->flags & flag;
}
return pakfire_timespec_delta(&now, &build->time_start);
}
-static int pakfire_build_jail_log_callback(struct pakfire* pakfire,
+static int pakfire_build_jail_log_callback(struct pakfire_ctx* ctx,
void* data, int priority, const char* line, size_t length) {
struct pakfire_build* build = data;
const unsigned int ms = (unsigned int)(t * 1000.0) % 1000;
if (h)
- return BUILD_LOG(build, priority, "[%02d:%02d:%02d.%04d] %.*s", h, m, s, ms, length, line);
+ pakfire_ctx_log_condition(ctx, priority, "[%02u:%02u:%02u.%04u] %.*s", h, m, s, ms, (int)length, line);
else if (m)
- return BUILD_LOG(build, priority, "[ %02d:%02d.%04d] %.*s", m, s, ms, length, line);
+ pakfire_ctx_log_condition(ctx, priority, "[ %02u:%02u.%04u] %.*s", m, s, ms, (int)length, line);
else
- return BUILD_LOG(build, priority, "[ %02d.%04d] %.*s", s, ms, length, line);
+ pakfire_ctx_log_condition(ctx, priority, "[ %02u.%04u] %.*s", s, ms, (int)length, line);
+
+ return 0;
}
static int __pakfire_build_setup_repo(struct pakfire* pakfire,
const char* name = pakfire_repo_get_name(repo);
- BUILD_DEBUG(build, "Exporting repository configuration for '%s'\n", name);
+ CTX_DEBUG(build->ctx, "Exporting repository configuration for '%s'\n", name);
// Make path for configuration file
r = pakfire_path(build->pakfire, path, PAKFIRE_CONFIG_DIR "/repos/%s.repo", name);
if (r) {
- BUILD_ERROR(build, "Could not make repository configuration path for %s: %m\n", name);
+ CTX_ERROR(build->ctx, "Could not make repository configuration path for %s: %m\n", name);
goto ERROR;
}
// Open the repository configuration
f = fopen(path, "w");
if (!f) {
- BUILD_ERROR(build, "Could not open %s for writing: %m\n", path);
+ CTX_ERROR(build->ctx, "Could not open %s for writing: %m\n", path);
goto ERROR;
}
// Write repository configuration
r = pakfire_repo_write_config(repo, f);
if (r) {
- BUILD_ERROR(build, "Could not write repository configuration for %s: %m\n", name);
+ CTX_ERROR(build->ctx, "Could not write repository configuration for %s: %m\n", name);
goto ERROR;
}
if (pakfire_path_exists(_path)) {
r = pakfire_jail_bind(build->jail, _path, _path, MS_RDONLY);
if (r) {
- BUILD_ERROR(build, "Could not bind-mount the repository at %s: %m\n", _path);
+ CTX_ERROR(build->ctx, "Could not bind-mount the repository at %s: %m\n", _path);
goto ERROR;
}
}
goto ERROR;
}
- BUILD_DEBUG(build, "Reading script from %s...\n", path);
+ CTX_DEBUG(build->ctx, "Reading script from %s...\n", path);
// Open the file
f = fopen(path, "r");
if (!f) {
- BUILD_ERROR(build, "Could not open script %s: %m\n", path);
+ CTX_ERROR(build->ctx, "Could not open script %s: %m\n", path);
goto ERROR;
}
// Read the file into a the buffer
r = pakfire_read_file_into_buffer(f, buffer, length);
if (r) {
- BUILD_ERROR(build, "Could not read script: %m\n");
+ CTX_ERROR(build->ctx, "Could not read script: %m\n");
goto ERROR;
}
char* script = NULL;
size_t length = 0;
- BUILD_DEBUG(build, "Running build script '%s'...\n", filename);
+ CTX_DEBUG(build->ctx, "Running build script '%s'...\n", filename);
// Read the script
r = pakfire_build_read_script(build, filename, &script, &length);
// Execute the script
r = pakfire_jail_exec_script(build->jail, script, length, args);
if (r)
- BUILD_ERROR(build, "Script '%s' failed with status %d\n", filename, r);
+ CTX_ERROR(build->ctx, "Script '%s' failed with status %d\n", filename, r);
if (script)
free(script);
if (r)
return r;
- BUILD_DEBUG(p->build, "Processing dependency: %s\n", dep);
+ CTX_DEBUG(ctx, "Processing dependency: %s\n", dep);
// Filter out any dependencies that are provided by this package
if (p->dep == PAKFIRE_PKG_REQUIRES) {
// Fetch the error message
r = pcre2_get_error_message(r, (PCRE2_UCHAR*)error, sizeof(error));
if (r < 0) {
- BUILD_ERROR(p->build, "Could not fetch PCRE error message: %m\n");
+ CTX_ERROR(ctx, "Could not fetch PCRE error message: %m\n");
r = 1;
goto ERROR;
}
- BUILD_ERROR(p->build, "Could not match the filter: %s\n", error);
+ CTX_ERROR(ctx, "Could not match the filter: %s\n", error);
r = 1;
goto ERROR;
// Match!
} else {
- BUILD_DEBUG(p->build, "Skipping dependency that has been filtered: %s\n", dep);
+ CTX_DEBUG(ctx, "Skipping dependency that has been filtered: %s\n", dep);
r = 0;
goto ERROR;
}
// Add dependency
r = pakfire_package_add_dep(p->pkg, p->dep, buffer);
if (r) {
- BUILD_ERROR(p->build, "Could not process dependency '%s': %m\n", buffer);
+ CTX_ERROR(ctx, "Could not process dependency '%s': %m\n", buffer);
return r;
}
goto ERROR;
SKIP:
- BUILD_DEBUG(p->build, "Skipping dependency that is provided by the package itself: %s\n", dep);
+ CTX_DEBUG(ctx, "Skipping dependency that is provided by the package itself: %s\n", dep);
ERROR:
if (match)
// Run the script
r = pakfire_build_run_script(build, script, args);
if (r)
- BUILD_ERROR(build, "%s returned with error %d\n", script, r);
+ CTX_ERROR(build->ctx, "%s returned with error %d\n", script, r);
return r;
}
if (r)
goto ERROR;
- BUILD_DEBUG(build, "%zu file(s) found\n", pakfire_filelist_length(filelist));
+ CTX_DEBUG(build->ctx, "%zu file(s) found\n", pakfire_filelist_length(filelist));
// Nothing to do if the filelist is empty
if (pakfire_filelist_is_empty(filelist))
// Find dependencies
r = pakfire_build_find_dependencies(build, makefile, namespace, pkg, filelist);
if (r) {
- BUILD_ERROR(build, "Finding dependencies failed: %m\n");
+ CTX_ERROR(build->ctx, "Finding dependencies failed: %m\n");
goto ERROR;
}
// Add it to the package
r = pakfire_packager_add_scriptlet(packager, scriptlet);
if (r) {
- BUILD_ERROR(build, "Could not add scriptlet %s\n", type);
+ CTX_ERROR(build->ctx, "Could not add scriptlet %s\n", type);
goto ERROR;
}
// Add scriptlet requirements
r = pakfire_build_add_scriptlet_requires(build, pkg, scriptlet);
if (r) {
- BUILD_ERROR(build, "Could not add scriptlet requirements: %m\n");
+ CTX_ERROR(build->ctx, "Could not add scriptlet requirements: %m\n");
goto ERROR;
}
goto ERROR;
}
- BUILD_INFO(build, "Building package '%s'...\n", name);
- BUILD_DEBUG(build, " buildroot = %s\n", buildroot);
+ CTX_INFO(build->ctx, "Building package '%s'...\n", name);
+ CTX_DEBUG(build->ctx, " buildroot = %s\n", buildroot);
// Fetch build architecture
const char* arch = pakfire_get_arch(build->pakfire);
// Fetch package from makefile
r = pakfire_parser_create_package(makefile, &pkg, NULL, namespace, arch);
if (r) {
- BUILD_ERROR(build, "Could not create package from makefile: %m\n");
+ CTX_ERROR(build->ctx, "Could not create package from makefile: %m\n");
goto ERROR;
}
// Write the finished package
r = pakfire_packager_finish_to_directory(packager, path, NULL);
if (r) {
- BUILD_ERROR(build, "pakfire_packager_finish() failed: %m\n");
+ CTX_ERROR(build->ctx, "pakfire_packager_finish() failed: %m\n");
goto ERROR;
}
if (!dump)
return 1;
- BUILD_INFO(build, "%s\n", dump);
+ CTX_INFO(build->ctx, "%s\n", dump);
free(dump);
return 0;
static int pakfire_build_packages(struct pakfire_build* build,
struct pakfire_parser* makefile) {
- BUILD_INFO(build, "Creating packages...");
+ CTX_INFO(build->ctx, "Creating packages...");
int r = 1;
const char* buildroot = pakfire_relpath(build->pakfire, build->buildroot);
// Fetch a list all all packages
char** packages = pakfire_parser_list_namespaces(makefile, "packages.package:*");
if (!packages) {
- BUILD_ERROR(build, "Could not find any packages: %m\n");
+ CTX_ERROR(build->ctx, "Could not find any packages: %m\n");
goto ERROR;
}
// Create the build script
char* script = pakfire_parser_expand(makefile, "build", template);
if (!script) {
- BUILD_ERROR(build, "Could not generate the build script for stage '%s': %m\n", stage);
+ CTX_ERROR(build->ctx, "Could not generate the build script for stage '%s': %m\n", stage);
goto ERROR;
}
- BUILD_INFO(build, "Running build stage '%s'\n", stage);
+ CTX_INFO(build->ctx, "Running build stage '%s'\n", stage);
// Import environment
// XXX is this a good idea?
r = pakfire_jail_import_env(build->jail, (const char**)envp);
if (r) {
- BUILD_ERROR(build, "Could not import environment: %m\n");
+ CTX_ERROR(build->ctx, "Could not import environment: %m\n");
goto ERROR;
}
// Run the script
r = pakfire_jail_exec_script(build->jail, script, strlen(script), NULL);
if (r)
- BUILD_ERROR(build, "Build stage '%s' failed with status %d\n", stage, r);
+ CTX_ERROR(build->ctx, "Build stage '%s' failed with status %d\n", stage, r);
ERROR:
if (envp) {
if (!pakfire_filelist_is_empty(removees)) {
if (description)
- BUILD_INFO(build, "%s\n", description);
+ CTX_INFO(build->ctx, "%s\n", description);
// Show all files which will be removed
pakfire_filelist_dump(removees, PAKFIRE_FILE_DUMP_FULL|PAKFIRE_FILE_DUMP_ISSUES);
// Create a filelist of all files in the build
r = pakfire_filelist_create(&filelist, build->pakfire);
if (r) {
- BUILD_ERROR(build, "Could not create filelist: %m\n");
+ CTX_ERROR(build->ctx, "Could not create filelist: %m\n");
goto ERROR;
}
return NULL;
}
-PAKFIRE_EXPORT void pakfire_build_set_log_callback(struct pakfire_build* build,
- pakfire_build_log_callback callback, void* data) {
- build->callbacks.log = callback;
- build->callbacks.log_data = data;
-}
-
PAKFIRE_EXPORT int pakfire_build_set_ccache_path(
struct pakfire_build* build, const char* path) {
// Check if this can be called
// Solve the transaction
r = pakfire_transaction_solve(transaction, 0, &problems);
if (r) {
- BUILD_ERROR(build, "Could not install build dependencies:\n%s\n", problems);
+ CTX_ERROR(build->ctx, "Could not install build dependencies:\n%s\n", problems);
goto ERROR;
}
r = pakfire_read_makefile(parser, build->pakfire, path, &error);
if (r) {
if (error) {
- BUILD_ERROR(build, "Could not parse makefile %s: %s\n", path,
+ CTX_ERROR(build->ctx, "Could not parse makefile %s: %s\n", path,
pakfire_parser_error_get_message(error));
} else {
- BUILD_ERROR(build, "Could not parse makefile %s: %m\n", path);
+ CTX_ERROR(build->ctx, "Could not parse makefile %s: %m\n", path);
}
goto ERROR;
// Run post build checks
r = pakfire_build_run_post_build_checks(build);
if (r) {
- BUILD_ERROR(build, "Post build checks failed\n");
+ CTX_ERROR(build->ctx, "Post build checks failed\n");
goto ERROR;
}
char* s = pakfire_file_dump(file, PAKFIRE_FILE_DUMP_FULL);
if (s) {
- BUILD_ERROR(build, "%s\n", s);
+ CTX_ERROR(build->ctx, "%s\n", s);
free(s);
}
goto ERROR;
if (!pakfire_filelist_is_empty(filelist)) {
- BUILD_ERROR(build, "Unpackaged files found:\n");
+ CTX_ERROR(build->ctx, "Unpackaged files found:\n");
r = pakfire_filelist_walk(filelist, __pakfire_build_unpackaged_file, build, 0);
if (r)
// Dependency Error
case 2:
- BUILD_ERROR(build, "Install test failed:\n%s\n", problems);
+ CTX_ERROR(build->ctx, "Install test failed:\n%s\n", problems);
break;
// Any other errors
default:
- BUILD_ERROR(build, "Install test failed: %m\n");
+ CTX_ERROR(build->ctx, "Install test failed: %m\n");
goto ERROR;
}
r = pakfire_transaction_solve(transaction, 0, &problems);
if (r) {
if (problems)
- BUILD_ERROR(build, "Could not install the source package:\n%s\n", problems);
+ CTX_ERROR(build->ctx, "Could not install the source package:\n%s\n", problems);
goto ERROR;
}
// Sanity check to see if we actually try to install anything
if (!changes) {
- BUILD_ERROR(build, "The source package did not get installed\n");
+ CTX_ERROR(build->ctx, "The source package did not get installed\n");
r = 1;
goto ERROR;
}
const char* nevra = pakfire_package_get_string(package, PAKFIRE_PKG_NEVRA);
const char* uuid = pakfire_package_get_string(package, PAKFIRE_PKG_UUID);
- BUILD_INFO(build, "Building %s (%s)...\n", nevra, uuid);
+ CTX_INFO(build->ctx, "Building %s (%s)...\n", nevra, uuid);
// Check if this package can be build in this environment
if (!pakfire_package_supports_build_arch(package, arch)) {
// Perform an install check to see whether we can build this at all
r = pakfire_package_installcheck(package, &problems, 0);
if (r) {
- BUILD_ERROR(build, "Cannot build %s:\n%s\n", nevra, problems);
+ CTX_ERROR(build->ctx, "Cannot build %s:\n%s\n", nevra, problems);
goto ERROR;
}
// Install the source package
r = pakfire_build_install_source_package(build, package);
if (r) {
- BUILD_ERROR(build, "Could not install the source package: %m\n");
+ CTX_ERROR(build->ctx, "Could not install the source package: %m\n");
goto ERROR;
}
// Mount the ccache
r = pakfire_build_mount_ccache(build);
if (r) {
- BUILD_ERROR(build, "Could not mount the ccache: %m\n");
+ CTX_ERROR(build->ctx, "Could not mount the ccache: %m\n");
goto ERROR;
}
// Create BUILDROOT
buildroot = pakfire_mkdtemp(build->buildroot);
if (!buildroot) {
- BUILD_ERROR(build, "Could not create BUILDROOT: %m\n");
+ CTX_ERROR(build->ctx, "Could not create BUILDROOT: %m\n");
goto ERROR;
}
// Create the packages
r = pakfire_build_packages(build, makefile);
if (r) {
- BUILD_ERROR(build, "Could not create packages: %m\n");
+ CTX_ERROR(build->ctx, "Could not create packages: %m\n");
goto ERROR;
}
if (r)
goto ERROR;
- BUILD_INFO(build, "Build successfully completed in %s\n", duration);
+ CTX_INFO(build->ctx, "Build successfully completed in %s\n", duration);
ERROR:
if (makefile)
struct pakfire_repo* local = NULL;
int r = 0;
- #warning Requires the legacy logger here... :(
+ struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
// Fetch local repository
local = pakfire_get_repo(pakfire, PAKFIRE_REPO_LOCAL);
if (!local) {
- ERROR(pakfire, "Could not find repository %s: %m\n", PAKFIRE_REPO_LOCAL);
+ CTX_ERROR(ctx, "Could not find repository %s: %m\n", PAKFIRE_REPO_LOCAL);
goto ERROR;
}
ERROR:
if (local)
pakfire_repo_unref(local);
+ if (ctx)
+ pakfire_ctx_unref(ctx);
return r;
}
struct pakfire_build* build = NULL;
int r;
+ // Fetch the context
+ struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
+
// Shells are always interactive
flags |= PAKFIRE_BUILD_INTERACTIVE;
// Create a new build environment
r = pakfire_build_create(&build, pakfire, NULL, flags);
if (r) {
- ERROR(pakfire, "Could not create build: %m\n");
+ CTX_ERROR(ctx, "Could not create build: %m\n");
goto ERROR;
}
ERROR:
if (build)
pakfire_build_unref(build);
+ if (ctx)
+ pakfire_ctx_unref(ctx);
return r;
}