const char* repo;
int flags;
+ // Exit Status
+ int status;
+
const char* arches[MAX_ARCHES];
unsigned int num_arches;
// Packages
char* packages[MAX_PACKAGES];
unsigned int num_packages;
-
- // Uploads
- char* uploads[MAX_UPLOADS];
- unsigned int num_uploads;
};
enum {
return 0;
}
+static int build_callback(struct pakfire_client* client, int status, const char* uuid, void* data) {
+ struct cli_local_args* local_args = data;
+
+ // Was there an error?
+ if (status) {
+ // Store the status
+ local_args->status = status;
+
+ // XXX Can we add any useful information which package it was and what the reason was?
+ fprintf(stderr, "Failed to create build\n");
+
+ return 0;
+ }
+
+ // XXX Here, we should actually send another API request that fetches the entire build object
+ // or change the callback so that we receive the raw (parsed) JSON objects.
+
+ // Show status
+ printf("Created build %s\n", uuid);
+
+ return 0;
+}
+
+// Called when an upload was successful
+static int upload_callback(struct pakfire_client* client,
+ pakfire_client_upload_status status, const char* path, const char* uuid, void* data) {
+ struct cli_local_args* local_args = data;
+ int r;
+
+ // Create the build
+ r = pakfire_client_build(client, uuid, local_args->repo,
+ local_args->arches, local_args->flags, build_callback, local_args);
+ if (r < 0) {
+ fprintf(stderr, "Failed to create build from %s: %s\n", path, strerror(-r));
+
+ // Store the status
+ local_args->status = r;
+ return r;
+ }
+
+ return 0;
+}
+
+static int ready_callback(struct pakfire_client* client, void* data) {
+ struct cli_local_args* local_args = data;
+ int r;
+
+ // XXX Should we check if the repository exists?
+
+ // Upload all packages
+ for (unsigned int i = 0; i < local_args->num_packages; i++) {
+ r = pakfire_client_upload(client, local_args->packages[i], NULL,
+ upload_callback, local_args);
+ if (r < 0) {
+ fprintf(stderr, "Failed to create upload %s: %s\n",
+ local_args->packages[i], strerror(-r));
+
+ // Store the status
+ local_args->status = r;
+ return r;
+ }
+ }
+
+ return 0;
+}
+
int cli_client_build(void* data, int argc, char* argv[]) {
struct cli_global_args* global_args = data;
struct cli_local_args local_args = {};
struct pakfire_client* client = NULL;
- char* upload = NULL;
int r;
// Parse the command line
if (r < 0)
goto ERROR;
-#if 0
- // Upload all packages
- for (unsigned int i = 0; i < local_args.num_packages; i++) {
- r = pakfire_client_upload(client, local_args.packages[i], NULL, &upload);
- if (r)
- goto ERROR;
+ // Set ready callback
+ pakfire_client_set_ready_callback(client, ready_callback, &local_args);
- // Store the upload ID
- local_args.uploads[local_args.num_uploads++] = upload;
- }
-#endif
-
- // No uploads
- if (!local_args.num_uploads)
+ // Run the client
+ r = pakfire_client_run(client);
+ if (r < 0)
goto ERROR;
- // Build all the things
- for (unsigned int i = 0; i < local_args.num_uploads; i++) {
- r = pakfire_client_build(client, local_args.uploads[i], local_args.repo,
- local_args.arches, local_args.flags);
- if (r)
- goto ERROR;
-
- // Free the upload
- free(local_args.uploads[i]);
- local_args.uploads[i] = NULL;
- }
+ // Return the status
+ r = local_args.status;
ERROR:
- // Delete & free all uploads that could not be processed
- for (unsigned int i = 0; i < local_args.num_uploads; i++) {
- if (local_args.uploads[i]) {
- pakfire_client_delete_upload(client, local_args.uploads[i]);
- free(local_args.uploads[i]);
- }
- }
if (client)
pakfire_client_unref(client);
// Build
-int pakfire_client_build(struct pakfire_client* self, const char* upload,
- const char* repo, const char** arches, int flags) {
+struct pakfire_client_build {
+ // Client
+ struct pakfire_client* client;
+
+ // Callback
+ pakfire_client_build_callback callback;
+ void* data;
+};
+
+static int pakfire_client_build_create(struct pakfire_client_build** build,
+ struct pakfire_client* client) {
+ struct pakfire_client_build* self = NULL;
+
+ // Allocate a new object
+ self = calloc(1, sizeof(*self));
+ if (!self)
+ return -errno;
+
+ // Store a reference to the client
+ self->client = pakfire_client_ref(client);
+
+ // Return the pointer
+ *build = self;
+
+ return 0;
+}
+
+static void pakfire_client_build_free(struct pakfire_client_build* self) {
+ if (self->client)
+ pakfire_client_unref(self->client);
+ free(self);
+}
+
+static int pakfire_client_build_response(struct pakfire_xfer* xfer,
+ pakfire_xfer_error_code_t status, struct json_object* response, void* data) {
+ struct pakfire_client_build* build = data;
+ const char* uuid = NULL;
+ int r = 0;
+
+ // Only process this if we have a callback
+ if (build->callback) {
+ // Extract the UUID from the response
+ r = pakfire_json_get_string(response, "uuid", &uuid);
+ if (r < 0)
+ goto ERROR;
+
+ // Call the callback
+ r = build->callback(build->client, status, uuid, build->data);
+ }
+
+ERROR:
+ pakfire_client_build_free(build);
+
+ return r;
+}
+
+int pakfire_client_build(struct pakfire_client* self, const char* upload, const char* repo,
+ const char** arches, int flags, pakfire_client_build_callback callback, void* data) {
+ struct pakfire_client_build* build = NULL;
struct pakfire_xfer* xfer = NULL;
struct json_object* request = NULL;
int r;
+ // Create a new build object
+ r = pakfire_client_build_create(&build, self);
+ if (r < 0)
+ goto ERROR;
+
+ // Store the callback
+ build->callback = callback;
+ build->data = data;
+
// Create a new xfer
r = pakfire_client_xfer_create(&xfer, self, "/api/v1/builds");
- if (r)
+ if (r < 0)
goto ERROR;
// Enable authentication
r = pakfire_client_xfer_auth(self, xfer);
- if (r)
+ if (r < 0)
goto ERROR;
// Create a new request object
if (r < 0)
goto ERROR;
- // Send the request
- r = pakfire_xfer_run_api_request(xfer, request, NULL);
+ // Set the request body
+ r = pakfire_xfer_set_json_payload(xfer, request);
+ if (r < 0)
+ goto ERROR;
+
+ // Register the callback
+ r = pakfire_xfer_set_response_callback(xfer, pakfire_client_build_response, build);
+ if (r < 0)
+ goto ERROR;
+
+ // Enqueue the transfer
+ r = pakfire_httpclient_enqueue(self->httpclient, xfer);
if (r < 0)
goto ERROR;
if (xfer)
pakfire_xfer_unref(xfer);
+ // Remove the build on error
+ if (r && build)
+ pakfire_client_build_free(build);
+
return r;
}
PAKFIRE_CLIENT_DISABLE_TESTS = (1 << 0),
} pakfire_client_build_flags_t;
-int pakfire_client_build(struct pakfire_client* client, const char* upload,
- const char* repo, const char** arches, int flags);
+typedef int (*pakfire_client_build_callback)
+ (struct pakfire_client* client, int status, const char* uuid, void* data);
+
+int pakfire_client_build(struct pakfire_client* client, const char* upload, const char* repo,
+ const char** arches, int flags, pakfire_client_build_callback callback, void* data);
// Uploads