]> git.ipfire.org Git - pakfire.git/commitdiff
client: Move builder stuff into a separate object
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 25 Jun 2025 15:48:48 +0000 (15:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 25 Jun 2025 15:48:48 +0000 (15:48 +0000)
This is messy as hell. I moved so much stuff around and lost track of
most of it. So this is a commit to kind of have some baseline.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/pakfire/builder.c [new file with mode: 0644]
src/pakfire/builder.h [new file with mode: 0644]
src/pakfire/client.c
src/pakfire/client.h
src/pakfire/daemon.c

index 6d832810d875227c2405adb6b02bc068cdd3525b..ceea71da8a452ccffd65931a10b6925c9d3cf502 100644 (file)
@@ -198,6 +198,8 @@ libpakfire_la_SOURCES = \
        src/pakfire/buffer.h \
        src/pakfire/build.c \
        src/pakfire/build.h \
+       src/pakfire/builder.c \
+       src/pakfire/builder.h \
        src/pakfire/cgroup.c \
        src/pakfire/cgroup.h \
        src/pakfire/client.c \
diff --git a/src/pakfire/builder.c b/src/pakfire/builder.c
new file mode 100644 (file)
index 0000000..431d653
--- /dev/null
@@ -0,0 +1,167 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 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 <errno.h>
+
+// systemd
+#include <systemd/sd-event.h>
+
+#include <pakfire/client.h>
+#include <pakfire/ctx.h>
+#include <pakfire/builder.h>
+#include <pakfire/util.h>
+#include <pakfire/xfer.h>
+
+struct pakfire_builder {
+       // Context
+       struct pakfire_ctx* ctx;
+
+       // Reference Counter
+       int nrefs;
+
+       // Event Loop
+       sd_event* loop;
+
+       // Client
+       struct pakfire_client* client;
+
+       // Control Connection
+       struct pakfire_xfer* control;
+
+       // Reconnect Timer & Holdoff Time
+       sd_event_source* reconnect_timer;
+       uint64_t reconnect_holdoff;
+};
+
+static void pakfire_builder_free(struct pakfire_builder* self) {
+       if (self->client)
+               pakfire_client_unref(self->client);
+       if (self->control)
+               pakfire_xfer_unref(self->control);
+       if (self->ctx)
+               pakfire_ctx_unref(self->ctx);
+       free(self);
+}
+
+int pakfire_builder_create(struct pakfire_builder** builder,
+               struct pakfire_ctx* ctx, struct pakfire_client* client) {
+       struct pakfire_builder* self = NULL;
+       int r;
+
+       // Allocate some memory
+       self = calloc(1, sizeof(*self));
+       if (!self)
+               return -errno;
+
+       // Store a reference to the context
+       self->ctx = pakfire_ctx_ref(ctx);
+
+       // Initialize the reference counter
+       self->nrefs = 1;
+
+       // Fetch a reference to the event loop
+       r = pakfire_ctx_loop(self->ctx, &self->loop);
+       if (r < 0)
+               goto ERROR;
+
+       // Store a reference to the client
+       self->client = pakfire_client_ref(client);
+
+       // Return the pointer
+       *builder = self;
+       return 0;
+
+ERROR:
+       pakfire_builder_free(self);
+       return r;
+}
+
+struct pakfire_builder* pakfire_builder_ref(struct pakfire_builder* self) {
+       ++self->nrefs;
+
+       return self;
+}
+
+struct pakfire_builder* pakfire_builder_unref(struct pakfire_builder* self) {
+       if (--self->nrefs > 0)
+               return self;
+
+       pakfire_builder_free(self);
+       return NULL;
+}
+
+int pakfire_builder_connect(struct pakfire_builder* self) {
+       // Bail if we are already connected
+       if (self->control)
+               return -EBUSY;
+
+       return pakfire_client_builder_connect(self->client, self);
+}
+
+int pakfire_builder_connected(struct pakfire_xfer* xfer, void* data) {
+       struct pakfire_builder* self = data;
+
+       DEBUG(self->ctx, "Builder connected\n");
+
+       // Store a reference to the control connection
+       self->control = pakfire_xfer_ref(xfer);
+
+       return 0;
+}
+
+/*
+       This function is called whenever the connection to the build service could not
+       be established or was interrupted. It will try to reconnect.
+*/
+int pakfire_builder_close(struct pakfire_xfer* xfer, int code, void* data) {
+       struct pakfire_builder* self = data;
+       int r;
+
+       // Remove the connection from the client
+       r = pakfire_client_builder_disconnected(self->client, xfer);
+       if (r < 0)
+               return r;
+
+       // Drop the control connection
+       if (self->control) {
+               pakfire_xfer_unref(self->control);
+               self->control = NULL;
+       }
+
+       INFO(self->ctx, "Will attempt to reconnect in %lu second(s)\n",
+               US_TO_S(self->reconnect_holdoff));
+
+       // Set the reconnection timer
+       r = sd_event_source_set_time_relative(
+                       self->reconnect_timer, self->reconnect_holdoff);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to set the reconnection timer: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Double the holdoff time
+       self->reconnect_holdoff *= 2;
+
+       // Cap reconnection attempts to every minute
+       if (self->reconnect_holdoff > S_TO_US(60))
+               self->reconnect_holdoff = S_TO_US(60);
+
+       return 0;
+}
diff --git a/src/pakfire/builder.h b/src/pakfire/builder.h
new file mode 100644 (file)
index 0000000..01b14bc
--- /dev/null
@@ -0,0 +1,42 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2025 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_BUILDER_H
+#define PAKFIRE_BUILDER_H
+
+struct pakfire_builder;
+
+#include <pakfire/client.h>
+#include <pakfire/ctx.h>
+
+int pakfire_builder_create(struct pakfire_builder** builder,
+       struct pakfire_ctx* ctx, struct pakfire_client* client);
+
+struct pakfire_builder* pakfire_builder_ref(struct pakfire_builder* self);
+struct pakfire_builder* pakfire_builder_unref(struct pakfire_builder* self);
+
+// Connect
+int pakfire_builder_connect(struct pakfire_builder* self);
+
+// Socket Callbacks
+int pakfire_builder_connected(struct pakfire_xfer* xfer, void* data);
+int pakfire_builder_close(struct pakfire_xfer* xfer, int code, void* data);
+
+#endif /* PAKFIRE_BUILDER_H */
index 2d79ace481f2780084e8aeb73f6c0c84df406dbc..dc293dbd6a096f6b86ff314734c83e32328e88ff 100644 (file)
@@ -705,6 +705,145 @@ ERROR:
        return r;
 }
 
+#if 0
+int pakfire_client_auth_builder(struct pakfire_client* self,
+               const char* username, const char* password) {
+       struct pakfire_xfer* xfer = NULL;
+       char hostname[HOST_NAME_MAX];
+       struct {
+               char* username;
+               char* password;
+               char* hostname;
+       } credentials = {};
+       char payload[2048];
+       int r;
+
+       // Fetch the hostname
+       r = gethostname(hostname, sizeof(hostname));
+       if (r)
+               goto ERROR;
+
+       // Create a new xfer
+       r = pakfire_client_xfer_create(&xfer, self, "/api/v1/auth/builder");
+       if (r < 0)
+               goto ERROR;
+
+       // Set the header
+       r = pakfire_xfer_add_header(xfer, "Content-Type: application/x-www-form-urlencoded");
+       if (r < 0)
+               goto ERROR;
+
+       // Escape the credentials
+       credentials.username = pakfire_xfer_escape(xfer, username);
+       credentials.password = pakfire_xfer_escape(xfer, password);
+
+       // Escape the hostname
+       credentials.hostname = pakfire_xfer_escape(xfer, hostname);
+
+       // Format the payload
+       r = pakfire_string_format(payload, "username=%s&password=%s&hostname=%s",
+               credentials.username, credentials.password, credentials.hostname);
+       if (r < 0)
+               goto ERROR;
+
+       // Set the payload
+       r = pakfire_xfer_set_payload(xfer, payload);
+       if (r < 0)
+               goto ERROR;
+
+       // Register the callback
+       r = pakfire_xfer_set_response_callback(xfer, pakfire_client_auth_response, self);
+       if (r < 0)
+               goto ERROR;
+
+       // Enqueue the transfer
+       r = pakfire_httpclient_enqueue(self->httpclient, xfer);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (xfer)
+               pakfire_xfer_unref(xfer);
+       if (credentials.username)
+               free(credentials.username);
+       if (credentials.password)
+               free(credentials.password);
+       if (credentials.hostname)
+               free(credentials.hostname);
+
+       return r;
+}
+#endif
+
+// Builder
+
+int pakfire_client_builder(struct pakfire_builder** builder, struct pakfire_client* self) {
+       struct pakfire_builder* b = NULL;
+       int r;
+
+       // Create a new builder
+       r = pakfire_builder_create(&b, self->ctx, self);
+       if (r < 0)
+               goto ERROR;
+
+       // Return the pointer
+       *builder = b;
+       return 0;
+
+ERROR:
+       if (b)
+               pakfire_builder_unref(b);
+
+       return r;
+}
+
+int pakfire_client_builder_connect(struct pakfire_client* self, struct pakfire_builder* builder) {
+       struct pakfire_xfer* xfer = NULL;
+       int r;
+
+       // Create a new xfer
+       r = pakfire_client_xfer_create(&xfer, self, "/api/v1/builders/control");
+       if (r < 0)
+               goto ERROR;
+
+       // Enable authentication
+       r = pakfire_client_xfer_auth(self, xfer);
+       if (r < 0)
+               goto ERROR;
+
+       // Make this a WebSocket connection
+       r = pakfire_xfer_socket(xfer,
+                       pakfire_builder_connected,
+                       NULL,
+                       NULL,
+                       pakfire_builder_close,
+                       builder);
+       if (r < 0)
+               goto ERROR;
+
+       // Enqueue the transfer
+       r = pakfire_httpclient_enqueue(self->httpclient, xfer);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (xfer)
+               pakfire_xfer_unref(xfer);
+
+       return r;
+}
+
+int pakfire_client_builder_disconnected(struct pakfire_client* self, struct pakfire_xfer* xfer) {
+       int r;
+
+       // Remove the connection from the client
+       r = pakfire_httpclient_dequeue(self->httpclient, xfer);
+       if (r < 0)
+               ERROR(self->ctx, "Failed to remove the control connection: %s\n", strerror(-r));
+
+       return r;
+}
+
 // Build
 
 int pakfire_client_build(struct pakfire_client* self, const char* upload,
index 0fc9b16d1d5959b03a5627365b326f359b8cf8e2..8237ae4ae7e7db6418f41dad2095e758fd057645 100644 (file)
@@ -25,7 +25,9 @@ struct pakfire_client;
 
 #include <json.h>
 
+#include <pakfire/builder.h>
 #include <pakfire/ctx.h>
+#include <pakfire/xfer.h>
 
 int pakfire_client_create(struct pakfire_client** client,
        struct pakfire_ctx* ctx, const char* url, const char* principal);
@@ -59,6 +61,14 @@ int pakfire_client_set_auth_callback(struct pakfire_client* client,
 
 int pakfire_client_auth_user(struct pakfire_client* client, const char* password);
 
+// Builder
+
+int pakfire_client_builder(struct pakfire_builder** builder, struct pakfire_client* self);
+
+// Low-level functions
+int pakfire_client_builder_connect(struct pakfire_client* self, struct pakfire_builder* builder);
+int pakfire_client_builder_disconnected(struct pakfire_client* self, struct pakfire_xfer* xfer);
+
 // Builds
 
 typedef enum pakfire_client_build_flags {
index 178c19328497b785bf0f8bac34d0afabbdf04a36..3ba57a6e96468e19ca394dc7b808a85f6635ef74 100644 (file)
@@ -28,6 +28,7 @@
 #include <systemd/sd-event.h>
 
 #include <pakfire/arch.h>
+#include <pakfire/builder.h>
 #include <pakfire/cgroup.h>
 #include <pakfire/client.h>
 #include <pakfire/ctx.h>
@@ -55,6 +56,9 @@ struct pakfire_daemon {
        // Pakfire Client
        struct pakfire_client* client;
 
+       // Builder
+       struct pakfire_builder* builder;
+
        // URL
        char url[PATH_MAX];
 
@@ -72,9 +76,6 @@ struct pakfire_daemon {
        sd_event_source* connect_timer;
        unsigned int reconnect_holdoff;
 
-       // Timer for submitting stats
-       sd_event_source* stats_timer;
-
        // cgroup
        struct pakfire_cgroup* cgroup;
 
@@ -130,6 +131,7 @@ static int pakfire_daemon_terminate(sd_event_source* source,
        return sd_event_exit(sd_event_source_get_event(source), 0);
 }
 
+#if 0
 static int pakfire_daemon_submit_stats(sd_event_source* s, uint64_t usec, void* p) {
        struct pakfire_daemon* daemon = p;
        struct pakfire_cpustat cpustat = {};
@@ -352,6 +354,7 @@ ERROR:
 
        return r;
 }
+#endif
 
 /*
  * Prevents that the system can be shut down when there are jobs running...
@@ -634,61 +637,6 @@ static int pakfire_daemon_send(struct pakfire_xfer* xfer, void* data) {
        return 0;
 }
 
-/*
-       This function is called whenever the connection to the build service could not
-       be established or was interrupted. It will try to reconnect.
-*/
-static int pakfire_daemon_close(struct pakfire_xfer* xfer, int code, void* data) {
-       struct pakfire_daemon* daemon = data;
-       int r;
-
-       // Remove the connection from the client
-       r = pakfire_httpclient_dequeue(daemon->httpclient, xfer);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Failed to remove the control connection: %s\n", strerror(-r));
-               return r;
-       }
-
-       // Drop the control connection
-       if (daemon->control) {
-               pakfire_xfer_unref(daemon->control);
-               daemon->control = NULL;
-       }
-
-       INFO(daemon->ctx, "Will attempt to reconnect in %lu second(s)\n",
-               daemon->reconnect_holdoff / S_TO_US(1));
-
-       // Set the reconnection timer
-       r = sd_event_source_set_time_relative(daemon->connect_timer, daemon->reconnect_holdoff);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Could not set the reconnection timer: %s\n", strerror(-r));
-               return r;
-       }
-
-       // Activate the timer
-       r = sd_event_source_set_enabled(daemon->connect_timer, SD_EVENT_ONESHOT);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Could not activate the connect timer: %s\n", strerror(-r));
-               return r;
-       }
-
-       // Double the holdoff time
-       daemon->reconnect_holdoff *= 2;
-
-       // Cap reconnection attempts to every minute
-       if (daemon->reconnect_holdoff > S_TO_US(60))
-               daemon->reconnect_holdoff = S_TO_US(60);
-
-       // Disable sending stats until we are connected
-       r = sd_event_source_set_enabled(daemon->stats_timer, SD_EVENT_OFF);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Could not disable the stats timer: %s\n", strerror(-r));
-               return r;
-       }
-
-       return 0;
-}
-
 static int pakfire_daemon_xfer_create(struct pakfire_xfer** xfer,
        struct pakfire_daemon* daemon, const char* url, ...) __attribute__((format(printf, 3, 4)));
 
@@ -721,158 +669,6 @@ ERROR:
        return r;
 }
 
-static int pakfire_daemon_connected(struct pakfire_xfer* xfer, void* data) {
-       struct pakfire_daemon* daemon = data;
-       int r;
-
-       DEBUG(daemon->ctx, "Connected!\n");
-
-       // Update the process title
-       r = pakfire_proctitle_set("pakfire-daemon: Connected\n");
-       if (r < 0)
-               return r;
-
-       // Store a reference to the control connection
-       daemon->control = pakfire_xfer_ref(xfer);
-
-       // Reset the holdoff timer
-       daemon->reconnect_holdoff = S_TO_US(1);
-
-       // Submit stats continuously
-       r = sd_event_source_set_enabled(daemon->stats_timer, SD_EVENT_ON);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Could not activate the stat timer: %s\n", strerror(-r));
-               return r;
-       }
-
-       return 0;
-}
-
-static int pakfire_daemon_connect(struct pakfire_daemon* daemon) {
-       struct pakfire_sysinfo sysinfo = {};
-       struct pakfire_cpuinfo cpuinfo = {};
-       struct pakfire_xfer* xfer = NULL;
-       const char* arch = NULL;
-       const char* id = NULL;
-       int r;
-
-       DEBUG(daemon->ctx, "Connecting...\n");
-
-       // Update the process title
-       r = pakfire_proctitle_set("pakfire-daemon: Connecting...\n");
-       if (r < 0)
-               return r;
-
-       // Fetch the distro
-       const struct pakfire_distro* distro = pakfire_ctx_get_distro(daemon->ctx);
-
-       // Fetch system information
-       r = pakfire_sysinfo(&sysinfo);
-       if (r < 0) {
-               ERROR(daemon->ctx, "Failed to fetch system info: %s\n", strerror(-r));
-               goto ERROR;
-       }
-
-       // Fetch native arch
-       arch = pakfire_arch_native();
-       if (!arch) {
-               ERROR(daemon->ctx, "Failed to fetch native arch: %s\n", strerror(errno));
-               r = -errno;
-               goto ERROR;
-       }
-
-       // Fetch CPU info
-       r = pakfire_cpuinfo(&cpuinfo);
-       if (r) {
-               ERROR(daemon->ctx, "Failed to fetch CPU info: %s\n", strerror(-r));
-               goto ERROR;
-       }
-
-       // Create a new xfer
-       r = pakfire_daemon_xfer_create(&xfer, daemon, "/api/v1/builders/control");
-       if (r)
-               goto ERROR;
-
-       // Enable authentication
-       r = pakfire_xfer_auth(xfer);
-       if (r)
-               goto ERROR;
-
-       // Send our version
-       r = pakfire_xfer_add_query(xfer, "version", "%s", PACKAGE_FULLVERSION);
-       if (r < 0)
-               goto ERROR;
-
-       // System Vendor
-       if (*sysinfo.vendor) {
-               r = pakfire_xfer_add_query(xfer, "sys_vendor", "%s", sysinfo.vendor);
-               if (r < 0)
-                       goto ERROR;
-       }
-
-       // System Model
-       if (*sysinfo.name) {
-               r = pakfire_xfer_add_query(xfer, "sys_name", "%s", sysinfo.name);
-               if (r < 0)
-                       goto ERROR;
-       }
-
-       // CPU Model
-       if (*cpuinfo.model) {
-               r = pakfire_xfer_add_query(xfer, "cpu_model", "%s", cpuinfo.model);
-               if (r < 0)
-                       goto ERROR;
-       }
-
-       // CPU Count
-       r = pakfire_xfer_add_query(xfer, "cpu_count", "%u", cpuinfo.count);
-       if (r < 0)
-               goto ERROR;
-
-       // Arch
-       r = pakfire_xfer_add_query(xfer, "arch", "%s", arch);
-       if (r < 0)
-               goto ERROR;
-
-       // OS
-       r = pakfire_xfer_add_query(xfer, "os_name", "%s", distro->pretty_name);
-       if (r < 0)
-               goto ERROR;
-
-       // Add all running jobs
-       for (unsigned int i = 0; i < MAX_JOBS; i++) {
-               if (!daemon->jobs[i])
-                       break;
-
-               // Fetch the job ID
-               id = pakfire_job_get_id(daemon->jobs[i]);
-               if (!id)
-                       continue;
-
-               // Add the job ID to the query
-               r = pakfire_xfer_add_query(xfer, "jobs", "%s", id);
-               if (r < 0)
-                       goto ERROR;
-       }
-
-       // Make this a WebSocket connection
-       r = pakfire_xfer_socket(xfer, pakfire_daemon_connected,
-               pakfire_daemon_recv, pakfire_daemon_send, pakfire_daemon_close, daemon);
-       if (r)
-               goto ERROR;
-
-       // Enqueue the transfer
-       r = pakfire_httpclient_enqueue(daemon->httpclient, xfer);
-       if (r)
-               goto ERROR;
-
-ERROR:
-       if (xfer)
-               pakfire_xfer_unref(xfer);
-
-       return r;
-}
-
 /*
        Called when the client is ready and we can start making connections...
 */
@@ -880,7 +676,7 @@ static int pakfire_daemon_ready(struct pakfire_client* client, void* data) {
        struct pakfire_daemon* self = data;
 
        // Connect the control connection
-       return pakfire_daemon_connect(self);
+       return pakfire_builder_connect(self->builder);
 }
 
 // Currently we are not doing anything here. We just need to block SIGCHLD.
@@ -959,8 +755,8 @@ static int pakfire_daemon_setup_bus(struct pakfire_daemon* daemon) {
 static int pakfire_daemon_setup_loop(struct pakfire_daemon* daemon) {
        int r;
 
-       // Fetch a reference to the default event loop
-       r = sd_event_default(&daemon->loop);
+       // Fetch a reference to the context's event loop
+       r = pakfire_ctx_loop(daemon->ctx, &daemon->loop);
        if (r < 0) {
                ERROR(daemon->ctx, "Could not setup event loop: %s\n", strerror(-r));
                return r;
@@ -1005,7 +801,6 @@ static int pakfire_daemon_setup_loop(struct pakfire_daemon* daemon) {
                ERROR(daemon->ctx, "Could not register the connection timer: %s\n", strerror(-r));
                return r;
        }
-#endif
 
        // Disable the reconnection timer until we are authenticated
        r = sd_event_source_set_enabled(daemon->connect_timer, SD_EVENT_OFF);
@@ -1028,6 +823,7 @@ static int pakfire_daemon_setup_loop(struct pakfire_daemon* daemon) {
                ERROR(daemon->ctx, "Could not disable the stats timer: %s\n", strerror(-r));
                return r;
        }
+#endif
 
        return 0;
 }
@@ -1064,10 +860,10 @@ static void pakfire_daemon_free(struct pakfire_daemon* daemon) {
        // Release shutdown inhibition
        pakfire_daemon_release_inhibit_shutdown(daemon);
 
+       if (daemon->builder)
+               pakfire_builder_unref(daemon->builder);
        if (daemon->connect_timer)
                sd_event_source_unref(daemon->connect_timer);
-       if (daemon->stats_timer)
-               sd_event_source_unref(daemon->stats_timer);
        if (daemon->httpclient)
                pakfire_httpclient_unref(daemon->httpclient);
        if (daemon->client)
@@ -1119,13 +915,18 @@ int pakfire_daemon_create(struct pakfire_daemon** daemon, struct pakfire_ctx* ct
                goto ERROR;
 
        // Connect to the build service
-       r = pakfire_client_create(&d->client, d->ctx, d->loop, d->url, NULL);
+       r = pakfire_client_create(&d->client, d->ctx, d->url, NULL);
        if (r < 0)
                goto ERROR;
 
        // Register the ready callback
        pakfire_client_set_ready_callback(d->client, pakfire_daemon_ready, d);
 
+       // Create builder
+       r = pakfire_client_builder(&d->builder, d->client);
+       if (r < 0)
+               goto ERROR;
+
        // Create the cgroup
        r = pakfire_cgroup_create(&d->cgroup, d->ctx, NULL, "pakfire-daemon", 0);
        if (r < 0)
@@ -1136,9 +937,6 @@ int pakfire_daemon_create(struct pakfire_daemon** daemon, struct pakfire_ctx* ct
        if (r < 0)
                goto ERROR;
 
-       // Reconnect after one second
-       d->reconnect_holdoff = S_TO_US(1);
-
        // Return the pointer
        *daemon = d;