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;
+ int r;
+
+ va_start(args, url);
+
+ // Create a new xfer
+ r = pakfire_xfer_create(&x, job->ctx, url, args);
+ if (r < 0)
+ goto ERROR;
+
+ // Set the base URL
+ r = pakfire_xfer_set_baseurl(x, pakfire_daemon_url(job->daemon));
+ if (r < 0)
+ goto ERROR;
+
+ // Success
+ *xfer = pakfire_xfer_ref(x);
+
+ERROR:
+ if (x)
+ pakfire_xfer_unref(x);
+ va_end(args);
+
+ return r;
+}
+
+static int pakfire_job_crashed(struct pakfire_job* job, const siginfo_t* si) {
+ struct pakfire_xfer* xfer = NULL;
+ char job_id[UUID_STR_LEN];
+ int r;
+
+ struct pakfire_job_log {
+ char* data;
+ size_t length;
+ } log = {};
+
+ // Format the job ID as string
+ uuid_unparse(job->job_id, job_id);
+
+ DEBUG(job->ctx, "Sending crash report...\n");
+
+ // Dump the log
+ r = pakfire_log_buffer_dump(job->log.buffer, &log.data, &log.length);
+ if (r < 0)
+ goto ERROR;
+
+ // Create a new transfer
+ r = pakfire_job_xfer_create(&xfer, job, "/api/v1/jobs/%s/crashed", job_id);
+ if (r < 0)
+ goto ERROR;
+
+ // Enable authentication
+ r = pakfire_xfer_auth(xfer);
+ if (r)
+ goto ERROR;
+
+ // Add the exit code
+ r = pakfire_xfer_add_param(xfer, "signo", "%d", si->si_status);
+ if (r < 0)
+ goto ERROR;
+
+ // If we have a log, let's send the log, too
+ // XXX THIS IS NOT QUITE IDEAL BECAUSE THE LOG COULD CONTAIN NULL-CHARACTERS
+ // WE SHOULD IMPLEMENT THIS WITH CURL'S MIME CALLBACK FUNCTIONS
+ if (log.data) {
+ r = pakfire_xfer_add_param(xfer, "log", "%.*s", (int)log.length, log.data);
+ if (r < 0)
+ goto ERROR;
+ }
+
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
+ if (r < 0)
+ goto ERROR;
+
+ERROR:
+ if (xfer)
+ pakfire_xfer_unref(xfer);
+ if (log.data)
+ free(log.data);
+
+ return r;
+}
+
/*
This method is triggered by SIGCHLD whenever the job exits
*/
int pakfire_job_exited(sd_event_source* s, const siginfo_t* si, void* data) {
struct pakfire_job* job = data;
char job_id[UUID_STR_LEN];
+ int r;
// Format the job ID as string
uuid_unparse(job->job_id, job_id);
// Update state
job->state = PAKFIRE_JOB_STATE_KILLED;
+ // Send some information about this
+ r = pakfire_job_crashed(job, si);
+ if (r < 0) {
+ ERROR(job->ctx, "Could not send crash report: %s\n", strerror(-r));
+ return r;
+ }
+
break;
}
return 0;
}
-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;
- int r;
-
- va_start(args, url);
-
- // Create a new xfer
- r = pakfire_xfer_create(&x, job->ctx, url, args);
- if (r < 0)
- goto ERROR;
-
- // Set the base URL
- r = pakfire_xfer_set_baseurl(x, pakfire_daemon_url(job->daemon));
- if (r < 0)
- goto ERROR;
-
- // Success
- *xfer = pakfire_xfer_ref(x);
-
-ERROR:
- if (x)
- pakfire_xfer_unref(x);
- va_end(args);
-
- return r;
-}
-
static int pakfire_job_connected(struct pakfire_xfer* xfer, void* data) {
struct pakfire_job* job = data;