]> git.ipfire.org Git - pakfire.git/commitdiff
job: Send a crash report in case the job crashes
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 26 Jan 2025 16:51:38 +0000 (16:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 26 Jan 2025 16:51:38 +0000 (16:51 +0000)
This currently does not seem to be able to send the log because it never
ends up in our buffer.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/job.c

index 18ce8c7648696b8da994c64be969593a31d96954..457d0f73544c327a7a17b644202883f0666921a1 100644 (file)
@@ -247,12 +247,103 @@ static void pakfire_job_free(struct pakfire_job* job) {
        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);
@@ -274,6 +365,13 @@ int pakfire_job_exited(sd_event_source* s, const siginfo_t* si, void* data) {
                        // 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;
        }
 
@@ -594,38 +692,6 @@ static int pakfire_job_closed(struct pakfire_xfer* xfer, int code, void* data) {
        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;