#include <errno.h>
#include <fcntl.h>
+#include <fts.h>
#include <limits.h>
#include <linux/sched.h>
#include <unistd.h>
#include <pakfire/log_buffer.h>
#include <pakfire/log_stream.h>
#include <pakfire/logging.h>
+#include <pakfire/path.h>
#include <pakfire/proctitle.h>
#include <pakfire/string.h>
#include <pakfire/syscalls.h>
struct pakfire_job_uploads {
char* logfile;
char** packages;
+
+ // Count how many uploads are running
+ int running;
} uploads;
};
free(job);
}
-static int pakfire_job_xfer_create(struct pakfire_xfer** xfer,
- struct pakfire_job* job, const char* url, ...) __attribute__((format(printf, 3, 4)));
-static int pakfire_job_xfer_create(struct pakfire_xfer** xfer,
- struct pakfire_job* job, const char* url, ...) {
- struct pakfire_xfer* x = NULL;
- va_list args;
+static int pakfire_job_finished(struct pakfire_job* self) {
int r;
- va_start(args, url);
-
- // Create a new xfer
- r = pakfire_xfer_create(&x, job->ctx, url, args);
+ // Submit the request
+ r = pakfire_client_job_finished(self->client,
+ self->id, self->uploads.logfile, self->uploads.packages);
if (r < 0)
- goto ERROR;
+ ERROR(self->ctx, "Failed to submit the finish request: %s\n", strerror(-r));
-#if 0
- // Set the base URL
- r = pakfire_xfer_set_baseurl(x, pakfire_daemon_url(job->daemon));
- if (r < 0)
- goto ERROR;
-#endif
+ // Let the builder know this is finished
+ return pakfire_builder_job_finished(self->builder, self);
+}
+
+static int pakfire_job_package_uploaded(struct pakfire_client* client,
+ pakfire_client_upload_status status, const char* path, const char* uuid, void* data) {
+ struct pakfire_job* self = data;
+ int r;
- // Success
- *xfer = pakfire_xfer_ref(x);
+ // Now we have one less uploads running
+ self->uploads.running--;
-ERROR:
- if (x)
- pakfire_xfer_unref(x);
- va_end(args);
+ switch (status) {
+ case PAKFIRE_CLIENT_UPLOAD_SUCCESSFUL:
+ // Store the ID of the upload
+ r = pakfire_strings_append(&self->uploads.packages, uuid);
+ if (r < 0)
+ return r;
+ break;
- return r;
+ default:
+ ERROR(self->ctx, "Failed to upload %s: %s\n", path, strerror(status));
+
+ // XXX What do we do here?
+
+ return status;
+ }
+
+ // Don't do anything if there are any other uploads still running
+ if (self->uploads.running)
+ return 0;
+
+ // Finish the job
+ return pakfire_job_finished(self);
}
static int pakfire_job_upload_packages(struct pakfire_job* self) {
- return 0; // XXX TODO
+ FTSENT* entry = NULL;
+ FTS* fts = NULL;
+ int r = 0;
+
+ char* paths[] = {
+ self->resultdir, NULL,
+ };
+
+ // Open the path
+ fts = fts_open(paths, FTS_PHYSICAL|FTS_NOCHDIR|FTS_NOSTAT, NULL);
+ if (!fts) {
+ ERROR(self->ctx, "Could not open %s: %m\n", self->resultdir);
+ r = -errno;
+ goto ERROR;
+ }
+
+ // Scan for everything
+ for (;;) {
+ // Fetch the next entry
+ entry = fts_read(fts);
+ if (!entry)
+ break;
+
+ // We only care about actual files
+ if (!(entry->fts_info & FTS_F))
+ continue;
+
+ // Skip anything that doesn't have the correct file extension
+ if (!pakfire_path_match("**.pfm", entry->fts_path))
+ continue;
+
+ // Upload the package
+ r = pakfire_client_upload(self->client, entry->fts_path, entry->fts_name,
+ pakfire_job_package_uploaded, self);
+ if (r < 0)
+ goto ERROR;
+
+ // Now there is one more upload running
+ self->uploads.running++;
+ }
+
+ERROR:
+ if (fts)
+ fts_close(fts);
+
+ return r;
}
/*
return pakfire_job_upload_packages(self);
}
-/*
- Called when the job has finished with status as the error code.
-*/
-static int pakfire_job_finished(struct pakfire_job* job, const siginfo_t* si) {
- struct pakfire_xfer* xfer = NULL;
- const char* filename = NULL;
- const char* path = NULL;
- int r;
-
- // Close the log file
- r = pakfire_log_file_close(job->log.file);
- if (r < 0) {
- ERROR(job->ctx, "Could not close the log file: %s\n", strerror(-r));
- goto ERROR;
- }
-
- // Fetch the filename of the log file
- filename = pakfire_log_file_filename(job->log.file);
- if (!filename) {
- ERROR(job->ctx, "Log file has no filename\n");
- r = -EINVAL;
- goto ERROR;
- }
-
- // Fetch the path of the log file
- path = pakfire_log_file_path(job->log.file);
- if (!path) {
- ERROR(job->ctx, "Log file has no path\n");
- r = -EINVAL;
- goto ERROR;
- }
-
- // Upload the log file
- r = pakfire_client_upload(job->client, path, filename, pakfire_job_logfile_uploaded, job);
- if (r < 0) {
- ERROR(job->ctx, "Could not upload the log file: %s\n", strerror(-r));
- goto ERROR;
- }
-
-#if 0
- // Create a new xfer
- r = pakfire_job_xfer_create(&xfer, job, "/api/v1/jobs/%s/finished", job->id);
- if (r < 0)
- goto ERROR;
-
- // Enable authentication
- r = pakfire_xfer_auth(xfer);
- if (r < 0)
- goto ERROR;
-
- // Has the job been successful?
- r = pakfire_xfer_add_param(xfer, "success", "%s", (status == 0) ? "true" : "false");
- if (r < 0)
- goto ERROR;
-
- // Logfile
- if (logfile) {
- r = pakfire_xfer_add_param(xfer, "logfile", "%s", logfile);
- if (r)
- goto ERROR;
- }
-
- // Packages
- if (job->uploads) {
- for (char** upload = job->uploads; *upload; upload++) {
- r = pakfire_xfer_add_param(xfer, "package", "%s", *upload);
- if (r < 0)
- goto ERROR;
- }
- }
-
- // Send the request
- r = pakfire_xfer_run_api_request(xfer, NULL, NULL);
- if (r < 0)
- goto ERROR;
-#endif
-
- // Let the builder know this is finished
- r = pakfire_builder_job_finished(job->builder, job);
-
-ERROR:
- if (xfer)
- pakfire_xfer_unref(xfer);
-
- return r;
-}
-
static int pakfire_job_result(struct pakfire_ctx* ctx, struct pakfire* pakfire,
struct pakfire_build* build, struct pakfire_archive* archive, void* data) {
- struct pakfire_job* job = data;
+ struct pakfire_job* self = data;
struct pakfire_package* pkg = NULL;
- char* uuid = NULL;
+ const char* filename = NULL;
+ const char* nevra = NULL;
+ char path[PATH_MAX];
int r;
// Fetch package metadata
goto ERROR;
// Fetch NEVRA
- const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
+ nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA);
if (!nevra) {
r = -EINVAL;
goto ERROR;
}
// Fetch filename
- const char* filename = pakfire_package_get_filename(pkg);
+ filename = pakfire_package_get_filename(pkg);
if (!filename) {
r = -EINVAL;
goto ERROR;
}
- // Fetch path
- const char* path = pakfire_archive_get_path(archive);
- if (!path) {
- r = -EINVAL;
+ // Make the path
+ r = pakfire_path_format(path, "%s/%s", self->resultdir, filename);
+ if (r < 0)
goto ERROR;
- }
-#if 0
- // Upload the file
- r = pakfire_client_upload(job->client, path, filename, &uuid);
+ // Copy the archive to the result directory
+ r = pakfire_archive_copy(archive, path);
if (r < 0) {
- ERROR(job->ctx, "Could not upload %s: %s\n", nevra, strerror(-r));
+ ERROR(self->ctx, "Failed to copy %s to %s: %s\n", nevra, path, strerror(-r));
goto ERROR;
}
-#endif
-
- // Store the ID of the upload
- r = pakfire_strings_append(&job->uploads.packages, uuid);
- if (r < 0)
- goto ERROR;
ERROR:
if (pkg)
pakfire_package_unref(pkg);
- if (uuid)
- free(uuid);
return r;
}
*/
static int pakfire_job_exited(sd_event_source* s, const siginfo_t* si, void* data) {
struct pakfire_job* job = data;
+ struct pakfire_xfer* xfer = NULL;
+ const char* filename = NULL;
+ const char* path = NULL;
+ int r;
switch (si->si_code) {
case CLD_EXITED:
break;
}
- // Signal that the job has finished
- return pakfire_job_finished(job, si);
+ // Close the log file
+ r = pakfire_log_file_close(job->log.file);
+ if (r < 0) {
+ ERROR(job->ctx, "Could not close the log file: %s\n", strerror(-r));
+ goto ERROR;
+ }
+
+ // Fetch the filename of the log file
+ filename = pakfire_log_file_filename(job->log.file);
+ if (!filename) {
+ ERROR(job->ctx, "Log file has no filename\n");
+ r = -EINVAL;
+ goto ERROR;
+ }
+
+ // Fetch the path of the log file
+ path = pakfire_log_file_path(job->log.file);
+ if (!path) {
+ ERROR(job->ctx, "Log file has no path\n");
+ r = -EINVAL;
+ goto ERROR;
+ }
+
+ // Upload the log file
+ r = pakfire_client_upload(job->client, path, filename, pakfire_job_logfile_uploaded, job);
+ if (r < 0) {
+ ERROR(job->ctx, "Could not upload the log file: %s\n", strerror(-r));
+ goto ERROR;
+ }
+
+ERROR:
+ if (xfer)
+ pakfire_xfer_unref(xfer);
+
+ return r;
}
static int pakfire_job_send_log(struct pakfire_job* job, int priority, const char* line, size_t length) {