Author: sandervanderburg
Date: Fri Oct 15 22:14:38 2010
New Revision: 24310
URL: https://svn.nixos.org/websvn/nix/?rev=24310&sc=1
Log:
Separated command-line interface from the disnix-build command
Added:
disnix/disnix/trunk/src/build/build.c
disnix/disnix/trunk/src/build/build.h
Modified:
disnix/disnix/trunk/src/build/Makefile.am
disnix/disnix/trunk/src/build/main.c
Modified: disnix/disnix/trunk/src/build/Makefile.am
==============================================================================
--- disnix/disnix/trunk/src/build/Makefile.am Fri Oct 15 20:06:55 2010
(r24309)
+++ disnix/disnix/trunk/src/build/Makefile.am Fri Oct 15 22:14:38 2010
(r24310)
@@ -1,7 +1,8 @@
AM_CPPFLAGS = -ggdb
bin_PROGRAMS = disnix-build
+noinst_HEADERS = build.h
-disnix_build_SOURCES = main.c
+disnix_build_SOURCES = build.c main.c
disnix_build_LDADD = ../libdistderivation/libdistderivation.la
../libmain/libmain.la ../libinterface/libinterface.la
disnix_build_CFLAGS = -I../libdistderivation -I../libmain -I../libinterface
Added: disnix/disnix/trunk/src/build/build.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ disnix/disnix/trunk/src/build/build.c Fri Oct 15 22:14:38 2010
(r24310)
@@ -0,0 +1,193 @@
+/*
+ * Disnix - A distributed application layer for Nix
+ * Copyright (C) 2008-2010 Sander van der Burg
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+ */
+
+#include "build.h"
+#include <derivationmapping.h>
+#include <client-interface.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define BUFFER_SIZE 4096
+
+static int distribute_derivations(gchar *interface, GArray *derivation_array)
+{
+ int status = 0;
+ unsigned int i;
+
+ for(i = 0; i < derivation_array->len; i++)
+ {
+ /* Retrieve derivation item from array */
+ DerivationItem *item = g_array_index(derivation_array, DerivationItem*,
i);
+
+ g_printerr("Distributing intra-dependency closure of derivation: %s to
target: %s\n", item->derivation, item->target);
+
+ /* Execute copy closure process */
+ status = wait_to_finish(exec_copy_closure_to(interface, item->target,
item->derivation));
+
+ /* On error stop the distribution process */
+ if(status != 0)
+ return status;
+ }
+
+ return status;
+}
+
+static int realise(gchar *interface, GArray *derivation_array, GArray
*result_array)
+{
+ /* Declarations */
+
+ unsigned int i;
+ GArray *output_array = g_array_new(FALSE, FALSE, sizeof(int));
+ int exit_status = 0;
+ int running_processes = 0;
+ int status;
+
+ /* Iterate over the derivation array and distribute the store derivation
closures to the target machines */
+
+ for(i = 0; i < derivation_array->len; i++)
+ {
+ int pipefd[2];
+ DerivationItem *item = g_array_index(derivation_array, DerivationItem*,
i);
+
+ status = exec_realise(interface, item->target, item->derivation,
pipefd);
+
+ if(status == -1)
+ {
+ g_printerr("Error with forking realise process!\n");
+ exit_status = -1;
+ }
+ else
+ {
+ g_array_append_val(output_array, pipefd[0]); /* Append read file
descriptor to array */
+ running_processes++;
+ }
+ }
+
+ /* Capture the output (Nix store components) of every realise process */
+
+ result_array = g_array_new(FALSE, FALSE, sizeof(gchar*));
+
+ for(i = 0; i < output_array->len; i++)
+ {
+ char line[BUFFER_SIZE];
+ int pipefd = g_array_index(output_array, int, i);
+ ssize_t line_size;
+
+ while((line_size = read(pipefd, line, BUFFER_SIZE - 1)) > 0)
+ {
+ line[line_size] = '\0';
+ puts(line);
+
+ if(g_strcmp0(line, "\n") != 0)
+ {
+ gchar *result;
+ result = g_strdup(line);
+ g_array_append_val(result_array, result);
+ }
+ }
+
+ close(pipefd);
+ }
+
+ /* Check statusses of the running processes */
+ for(i = 0; i < running_processes; i++)
+ {
+ /* Wait until a realise process is finished */
+ wait(&status);
+
+ /* If one of the processes fail, change the exit status */
+ if(WEXITSTATUS(status) != 0)
+ exit_status = WEXITSTATUS(status);
+ }
+
+ /* Cleanup */
+ g_array_free(output_array, TRUE);
+
+ /* Return the exit status, which is 0 if everything succeeds */
+ return exit_status;
+}
+
+static int retrieve_results(gchar *interface, GArray *derivation_array, GArray
*result_array)
+{
+ unsigned int i;
+ int status = 0;
+
+ /* Iterate over the derivation array and copy the build results back */
+ for(i = 0; i < derivation_array->len; i++)
+ {
+ gchar *result;
+ DerivationItem *item;
+
+ result = g_array_index(result_array, gchar*, i);
+ item = g_array_index(derivation_array, DerivationItem*, i);
+
+ g_printerr("Copying result: %s from: %s\n", result, item->target);
+
+ status = wait_to_finish(exec_copy_closure_from(interface, item->target,
result));
+
+ /* On error stop build process */
+ if(status != 0)
+ return status;
+ }
+
+ return status;
+}
+
+static void delete_result_array(GArray *result_array)
+{
+ unsigned int i;
+
+ for(i = 0; i < result_array->len; i++)
+ {
+ gchar *result = g_array_index(result_array, gchar*, i);
+ g_free(result);
+ }
+
+ g_array_free(result_array, TRUE);
+}
+
+int build(gchar *interface, gchar *distributed_derivation_file)
+{
+ GArray *derivation_array =
create_derivation_array(distributed_derivation_file);
+ int exit_status = 0;
+
+ /* Distribute derivations to target machines */
+ if((exit_status = distribute_derivations(interface, derivation_array)) ==
0)
+ {
+ GArray *result_array = g_array_new(FALSE, FALSE, sizeof(gchar*));
+
+ /* Realise derivations on target machines */
+ if((exit_status = realise(interface, derivation_array, result_array))
== 0)
+ {
+ /* Retrieve back the build results */
+ exit_status = retrieve_results(interface, derivation_array,
result_array);
+ }
+
+ /* Cleanup */
+ delete_result_array(result_array);
+ }
+
+ /* Cleanup */
+ delete_derivation_array(derivation_array);
+
+ /* Return the exit status, which is 0 if everything succeeds */
+ return exit_status;
+}
Added: disnix/disnix/trunk/src/build/build.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ disnix/disnix/trunk/src/build/build.h Fri Oct 15 22:14:38 2010
(r24310)
@@ -0,0 +1,35 @@
+/*
+ * Disnix - A distributed application layer for Nix
+ * Copyright (C) 2008-2010 Sander van der Burg
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+ */
+
+#ifndef __BUILD_H
+#define __BUILD_H
+#include <glib.h>
+
+/**
+ * Executes a distributed build. First Nix store derivation closures are copied
+ * to target machines in the network. Then the remote builds are performed
+ * and finally the build results are copied back to the coordinator machine.
+ *
+ * @param interface Path to the client interface executable
+ * @param distributed_derivation_file Path to the distributed derivation file
+ * @return 0 if everything succeeds, or else a non-zero exit value
+ */
+int build(gchar *interface, gchar *distributed_derivation_file);
+
+#endif
Modified: disnix/disnix/trunk/src/build/main.c
==============================================================================
--- disnix/disnix/trunk/src/build/main.c Fri Oct 15 20:06:55 2010
(r24309)
+++ disnix/disnix/trunk/src/build/main.c Fri Oct 15 22:14:38 2010
(r24310)
@@ -18,17 +18,9 @@
*/
#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
#include <getopt.h>
#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <derivationmapping.h>
#include <defaultoptions.h>
-#include <client-interface.h>
-
-#define BUFFER_SIZE 4096
static void print_usage()
{
@@ -37,19 +29,6 @@
fprintf(stderr, "disnix-build {-h | --help}\n");
}
-static void delete_result_array(GArray *result_array)
-{
- unsigned int i;
-
- for(i = 0; i < result_array->len; i++)
- {
- gchar *result = g_array_index(result_array, gchar*, i);
- g_free(result);
- }
-
- g_array_free(result_array, TRUE);
-}
-
int main(int argc, char *argv[])
{
/* Declarations */
@@ -82,138 +61,9 @@
if(optind >= argc)
{
- fprintf(stderr, "ERROR: No manifest specified!\n");
+ fprintf(stderr, "ERROR: No distributed derivation file specified!\n");
return 1;
}
else
- {
- /* Generate a distribution array from the manifest file */
- GArray *derivation_array = create_derivation_array(argv[optind]);
-
- if(derivation_array == NULL)
- return -1;
- else
- {
- unsigned int i, running_processes = 0;
- int exit_status = 0;
- int status;
-
- GArray *output_array;
- GArray *result_array;
-
- /* Iterate over the derivation array and distribute the store
derivation closures to the target machines */
- for(i = 0; i < derivation_array->len; i++)
- {
- DerivationItem *item = g_array_index(derivation_array,
DerivationItem*, i);
- int status;
-
- fprintf(stderr, "Distributing intra-dependency closure of
derivation: %s to target: %s\n", item->derivation, item->target);
-
- status = wait_to_finish(exec_copy_closure_to(interface,
item->target, item->derivation));
-
- /* On error stop the build process */
- if(status != 0)
- {
- delete_derivation_array(derivation_array);
- return status;
- }
- }
-
- /* Iterate over the derivation array and invoke processes that
realise the derivations remotely */
-
- output_array = g_array_new(FALSE, FALSE, sizeof(int));
-
- for(i = 0; i < derivation_array->len; i++)
- {
- int pipefd[2];
- int status;
- DerivationItem *item = g_array_index(derivation_array,
DerivationItem*, i);
-
- status = exec_realise(interface, item->target,
item->derivation, pipefd);
-
- if(status == -1)
- {
- fprintf(stderr, "Error with forking realise process!\n");
- exit_status = -1;
- }
- else
- {
- g_array_append_val(output_array, pipefd[0]); /* Append read
file descriptor to array */
- running_processes++;
- }
- }
-
- result_array = g_array_new(FALSE, FALSE, sizeof(gchar*));
-
- /* Capture the output (Nix store components) of every realise
process */
-
- for(i = 0; i < output_array->len; i++)
- {
- char line[BUFFER_SIZE];
- int pipefd = g_array_index(output_array, int, i);
- ssize_t line_size;
-
- while((line_size = read(pipefd, line, BUFFER_SIZE - 1)) > 0)
- {
- line[line_size] = '\0';
- puts(line);
-
- if(g_strcmp0(line, "\n") != 0)
- {
- gchar *result;
- result = g_strdup(line);
- g_array_append_val(result_array, result);
- }
- }
-
- close(pipefd);
- }
-
- /* Check statusses of the running processes */
- for(i = 0; i < running_processes; i++)
- {
- /* Wait until a realise process is finished */
- wait(&status);
-
- /* If one of the processes fail, change the exit status */
- if(WEXITSTATUS(status) != 0)
- exit_status = WEXITSTATUS(status);
- }
-
- if(exit_status == 0)
- {
- /* Retrieve back the realised closures and import them into the
Nix store of the host */
-
- for(i = 0; i < derivation_array->len; i++)
- {
- gchar *result;
- DerivationItem *item;
- int status;
-
- result = g_array_index(result_array, gchar*, i);
- item = g_array_index(derivation_array, DerivationItem*, i);
-
- fprintf(stderr, "Copying result: %s from: %s\n", result,
item->target);
-
- status = wait_to_finish(exec_copy_closure_from(interface,
item->target, result));
-
- /* On error stop build process */
- if(status != 0)
- {
- g_array_free(output_array, TRUE);
- delete_result_array(result_array);
- delete_derivation_array(derivation_array);
- return status;
- }
- }
- }
-
- /* Cleanup */
- g_array_free(output_array, TRUE);
- delete_result_array(result_array);
- delete_derivation_array(derivation_array);
-
- return exit_status;
- }
- }
+ build(interface, argv[optind]); /* Perform distributed build operation
*/
}
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits