You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

245 lines
6.6 KiB

  1. /* GNU Guix --- Functional package management for GNU
  2. Copyright (C) 2012, 2013 Ludovic Courtès <ludo@gnu.org>
  3. This file is part of GNU Guix.
  4. GNU Guix is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at
  7. your option) any later version.
  8. GNU Guix is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
  14. #include <config.h>
  15. #include <types.hh>
  16. #include "shared.hh"
  17. #include <globals.hh>
  18. #include <util.hh>
  19. #include <gcrypt.h>
  20. #include <stdlib.h>
  21. #include <argp.h>
  22. #include <unistd.h>
  23. #include <sys/types.h>
  24. #include <exception>
  25. /* Variables used by `nix-daemon.cc'. */
  26. volatile ::sig_atomic_t blockInt;
  27. char **argvSaved;
  28. using namespace nix;
  29. /* Entry point in `nix-daemon.cc'. */
  30. extern void run (Strings args);
  31. /* Command-line options. */
  32. const char *argp_program_version =
  33. "guix-daemon (" PACKAGE_NAME ") " PACKAGE_VERSION;
  34. const char *argp_program_bug_address = PACKAGE_BUGREPORT;
  35. static char doc[] =
  36. "guix-daemon -- perform derivation builds and store accesses\
  37. \v\
  38. This program is a daemon meant to run in the background. It serves \
  39. requests sent over a Unix-domain socket. It accesses the store, and \
  40. builds derivations on behalf of its clients.";
  41. #define GUIX_OPT_SYSTEM 1
  42. #define GUIX_OPT_DISABLE_CHROOT 2
  43. #define GUIX_OPT_BUILD_USERS_GROUP 3
  44. #define GUIX_OPT_CACHE_FAILURES 4
  45. #define GUIX_OPT_LOSE_LOGS 5
  46. #define GUIX_OPT_DISABLE_LOG_COMPRESSION 6
  47. #define GUIX_OPT_DISABLE_STORE_OPTIMIZATION 7
  48. #define GUIX_OPT_IMPERSONATE_LINUX_26 8
  49. #define GUIX_OPT_DEBUG 9
  50. #define GUIX_OPT_CHROOT_DIR 10
  51. #define GUIX_OPT_LISTEN 11
  52. static const struct argp_option options[] =
  53. {
  54. { "system", GUIX_OPT_SYSTEM, "SYSTEM", 0,
  55. "Assume SYSTEM as the current system type" },
  56. { "cores", 'c', "N", 0,
  57. "Use N CPU cores to build each derivation; 0 means as many as available" },
  58. { "max-jobs", 'M', "N", 0,
  59. "Allow at most N build jobs" },
  60. { "disable-chroot", GUIX_OPT_DISABLE_CHROOT, 0, 0,
  61. "Disable chroot builds"
  62. #ifndef HAVE_CHROOT
  63. " (chroots are not supported in this configuration, so "
  64. "this option has no effect)"
  65. #endif
  66. },
  67. { "chroot-directory", GUIX_OPT_CHROOT_DIR, "DIR", 0,
  68. "Add DIR to the build chroot"
  69. #ifndef HAVE_CHROOT
  70. " (chroots are not supported in this configuration, so "
  71. "this option has no effect)"
  72. #endif
  73. },
  74. { "build-users-group", GUIX_OPT_BUILD_USERS_GROUP, "GROUP", 0,
  75. "Perform builds as a user of GROUP" },
  76. { "cache-failures", GUIX_OPT_CACHE_FAILURES, 0, 0,
  77. "Cache build failures" },
  78. { "lose-logs", GUIX_OPT_LOSE_LOGS, 0, 0,
  79. "Do not keep build logs" },
  80. { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0,
  81. "Disable compression of the build logs" },
  82. { "disable-store-optimization", GUIX_OPT_DISABLE_STORE_OPTIMIZATION, 0, 0,
  83. "Disable automatic file \"deduplication\" in the store" },
  84. { "impersonate-linux-2.6", GUIX_OPT_IMPERSONATE_LINUX_26, 0, 0,
  85. "Impersonate Linux 2.6"
  86. #ifndef HAVE_SYS_PERSONALITY_H
  87. " (this option has no effect in this configuration)"
  88. #endif
  89. },
  90. { "listen", GUIX_OPT_LISTEN, "SOCKET", 0,
  91. "Listen for connections on SOCKET" },
  92. { "debug", GUIX_OPT_DEBUG, 0, 0,
  93. "Produce debugging output" },
  94. { 0, 0, 0, 0, 0 }
  95. };
  96. /* Parse a single option. */
  97. static error_t
  98. parse_opt (int key, char *arg, struct argp_state *state)
  99. {
  100. switch (key)
  101. {
  102. case GUIX_OPT_DISABLE_CHROOT:
  103. settings.useChroot = false;
  104. break;
  105. case GUIX_OPT_CHROOT_DIR:
  106. settings.dirsInChroot.insert (arg);
  107. break;
  108. case GUIX_OPT_DISABLE_LOG_COMPRESSION:
  109. settings.compressLog = false;
  110. break;
  111. case GUIX_OPT_BUILD_USERS_GROUP:
  112. settings.buildUsersGroup = arg;
  113. break;
  114. case GUIX_OPT_DISABLE_STORE_OPTIMIZATION:
  115. settings.autoOptimiseStore = false;
  116. break;
  117. case GUIX_OPT_CACHE_FAILURES:
  118. settings.cacheFailure = true;
  119. break;
  120. case GUIX_OPT_IMPERSONATE_LINUX_26:
  121. settings.impersonateLinux26 = true;
  122. break;
  123. case GUIX_OPT_LOSE_LOGS:
  124. settings.keepLog = false;
  125. break;
  126. case GUIX_OPT_LISTEN:
  127. try
  128. {
  129. settings.nixDaemonSocketFile = canonPath (arg);
  130. }
  131. catch (std::exception &e)
  132. {
  133. fprintf (stderr, "error: %s\n", e.what ());
  134. exit (EXIT_FAILURE);
  135. }
  136. break;
  137. case GUIX_OPT_DEBUG:
  138. verbosity = lvlDebug;
  139. break;
  140. case 'c':
  141. settings.buildCores = atoi (arg);
  142. break;
  143. case 'M':
  144. settings.maxBuildJobs = atoi (arg);
  145. break;
  146. case GUIX_OPT_SYSTEM:
  147. settings.thisSystem = arg;
  148. break;
  149. default:
  150. return ARGP_ERR_UNKNOWN;
  151. }
  152. return 0;
  153. }
  154. /* Argument parsing. */
  155. static struct argp argp = { options, parse_opt, 0, doc };
  156. int
  157. main (int argc, char *argv[])
  158. {
  159. Strings nothing;
  160. /* Initialize libgcrypt. */
  161. if (!gcry_check_version (GCRYPT_VERSION))
  162. {
  163. fprintf (stderr, "error: libgcrypt version mismatch\n");
  164. exit (EXIT_FAILURE);
  165. }
  166. #ifdef HAVE_CHROOT
  167. settings.useChroot = true;
  168. #else
  169. settings.useChroot = false;
  170. #endif
  171. argvSaved = argv;
  172. try
  173. {
  174. settings.processEnvironment ();
  175. /* Use our substituter by default. */
  176. settings.substituters.clear ();
  177. string subs = getEnv ("NIX_SUBSTITUTERS", "default");
  178. if (subs == "default")
  179. /* XXX: No substituters until we have something that works. */
  180. settings.substituters.clear ();
  181. // settings.substituters.push_back (settings.nixLibexecDir
  182. // + "/guix/substitute-binary");
  183. else
  184. settings.substituters = tokenizeString<Strings> (subs, ":");
  185. argp_parse (&argp, argc, argv, 0, 0, 0);
  186. if (geteuid () == 0 && settings.buildUsersGroup.empty ())
  187. fprintf (stderr, "warning: daemon is running as root, so "
  188. "using `--build-users-group' is highly recommended\n");
  189. #ifdef HAVE_CHROOT
  190. if (settings.useChroot)
  191. {
  192. foreach (PathSet::iterator, i, settings.dirsInChroot)
  193. {
  194. printMsg (lvlDebug,
  195. format ("directory `%1%' added to the chroot") % *i);
  196. }
  197. }
  198. #endif
  199. printMsg (lvlDebug,
  200. format ("listening on `%1%'") % settings.nixDaemonSocketFile);
  201. run (nothing);
  202. }
  203. catch (std::exception &e)
  204. {
  205. fprintf (stderr, "error: %s\n", e.what ());
  206. return EXIT_FAILURE;
  207. }
  208. return EXIT_SUCCESS; /* never reached */
  209. }