1 /* GNU Guix --- Functional package management for GNU
2 Copyright (C) 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
4 This file is part of GNU Guix.
6 GNU Guix is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or (at
9 your option) any later version.
11 GNU Guix is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
31 #include <sys/types.h>
39 /* Variables used by `nix-daemon.cc'. */
40 volatile ::sig_atomic_t blockInt
;
45 /* Entry point in `nix-daemon.cc'. */
46 extern void run (Strings args
);
49 /* Command-line options. */
52 #define _(str) gettext (str)
53 static const char guix_textdomain
[] = "guix";
56 const char *argp_program_version
=
57 "guix-daemon (" PACKAGE_NAME
") " PACKAGE_VERSION
;
58 const char *argp_program_bug_address
= PACKAGE_BUGREPORT
;
61 n_("guix-daemon -- perform derivation builds and store accesses")
63 n_("This program is a daemon meant to run in the background. It serves \
64 requests sent over a Unix-domain socket. It accesses the store, and \
65 builds derivations on behalf of its clients.");
67 #define GUIX_OPT_SYSTEM 1
68 #define GUIX_OPT_DISABLE_CHROOT 2
69 #define GUIX_OPT_BUILD_USERS_GROUP 3
70 #define GUIX_OPT_CACHE_FAILURES 4
71 #define GUIX_OPT_LOSE_LOGS 5
72 #define GUIX_OPT_DISABLE_LOG_COMPRESSION 6
73 #define GUIX_OPT_DISABLE_DEDUPLICATION 7
74 #define GUIX_OPT_IMPERSONATE_LINUX_26 8
75 #define GUIX_OPT_DEBUG 9
76 #define GUIX_OPT_CHROOT_DIR 10
77 #define GUIX_OPT_LISTEN 11
78 #define GUIX_OPT_NO_SUBSTITUTES 12
79 #define GUIX_OPT_SUBSTITUTE_URLS 13
80 #define GUIX_OPT_NO_BUILD_HOOK 14
81 #define GUIX_OPT_GC_KEEP_OUTPUTS 15
82 #define GUIX_OPT_GC_KEEP_DERIVATIONS 16
83 #define GUIX_OPT_BUILD_ROUNDS 17
85 static const struct argp_option options
[] =
87 { "system", GUIX_OPT_SYSTEM
, n_("SYSTEM"), 0,
88 n_("assume SYSTEM as the current system type") },
89 { "cores", 'c', n_("N"), 0,
90 n_("use N CPU cores to build each derivation; 0 means as many as available")
92 { "max-jobs", 'M', n_("N"), 0,
93 n_("allow at most N build jobs") },
94 { "disable-chroot", GUIX_OPT_DISABLE_CHROOT
, 0, 0,
95 n_("disable chroot builds") },
96 { "chroot-directory", GUIX_OPT_CHROOT_DIR
, n_("DIR"), 0,
97 n_("add DIR to the build chroot") },
98 { "build-users-group", GUIX_OPT_BUILD_USERS_GROUP
, n_("GROUP"), 0,
99 n_("perform builds as a user of GROUP") },
100 { "no-substitutes", GUIX_OPT_NO_SUBSTITUTES
, 0, 0,
101 n_("do not use substitutes") },
102 { "substitute-urls", GUIX_OPT_SUBSTITUTE_URLS
, n_("URLS"), 0,
103 n_("use URLS as the default list of substitute providers") },
104 { "no-build-hook", GUIX_OPT_NO_BUILD_HOOK
, 0, 0,
105 n_("do not use the 'build hook'") },
106 { "cache-failures", GUIX_OPT_CACHE_FAILURES
, 0, 0,
107 n_("cache build failures") },
108 { "rounds", GUIX_OPT_BUILD_ROUNDS
, "N", 0,
109 n_("build each derivation N times in a row") },
110 { "lose-logs", GUIX_OPT_LOSE_LOGS
, 0, 0,
111 n_("do not keep build logs") },
112 { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION
, 0, 0,
113 n_("disable compression of the build logs") },
115 /* '--disable-deduplication' was known as '--disable-store-optimization'
116 up to Guix 0.7 included, so keep the alias around. */
117 { "disable-deduplication", GUIX_OPT_DISABLE_DEDUPLICATION
, 0, 0,
118 n_("disable automatic file \"deduplication\" in the store") },
119 { "disable-store-optimization", GUIX_OPT_DISABLE_DEDUPLICATION
, 0,
120 OPTION_ALIAS
| OPTION_HIDDEN
, NULL
},
122 { "impersonate-linux-2.6", GUIX_OPT_IMPERSONATE_LINUX_26
, 0,
123 #ifdef HAVE_SYS_PERSONALITY_H
128 n_("impersonate Linux 2.6")
130 { "gc-keep-outputs", GUIX_OPT_GC_KEEP_OUTPUTS
,
131 "yes/no", OPTION_ARG_OPTIONAL
,
132 n_("tell whether the GC must keep outputs of live derivations") },
133 { "gc-keep-derivations", GUIX_OPT_GC_KEEP_DERIVATIONS
,
134 "yes/no", OPTION_ARG_OPTIONAL
,
135 n_("tell whether the GC must keep derivations corresponding \
138 { "listen", GUIX_OPT_LISTEN
, n_("SOCKET"), 0,
139 n_("listen for connections on SOCKET") },
140 { "debug", GUIX_OPT_DEBUG
, 0, 0,
141 n_("produce debugging output") },
146 /* Convert ARG to a Boolean value, or throw an error if it does not denote a
149 string_to_bool (const char *arg
, bool dflt
= true)
153 else if (strcasecmp (arg
, "yes") == 0)
155 else if (strcasecmp (arg
, "no") == 0)
158 throw nix::Error (format ("'%1%': invalid Boolean value") % arg
);
161 /* Parse a single option. */
163 parse_opt (int key
, char *arg
, struct argp_state
*state
)
167 case GUIX_OPT_DISABLE_CHROOT
:
168 settings
.useChroot
= false;
170 case GUIX_OPT_CHROOT_DIR
:
172 std::string chroot_dirs
;
174 chroot_dirs
= settings
.get ("build-extra-chroot-dirs",
176 if (chroot_dirs
== "")
179 chroot_dirs
= chroot_dirs
+ " " + arg
;
180 settings
.set("build-extra-chroot-dirs", chroot_dirs
);
183 case GUIX_OPT_DISABLE_LOG_COMPRESSION
:
184 settings
.compressLog
= false;
186 case GUIX_OPT_BUILD_USERS_GROUP
:
187 settings
.buildUsersGroup
= arg
;
189 case GUIX_OPT_DISABLE_DEDUPLICATION
:
190 settings
.autoOptimiseStore
= false;
192 case GUIX_OPT_CACHE_FAILURES
:
193 settings
.cacheFailure
= true;
195 case GUIX_OPT_BUILD_ROUNDS
:
198 unsigned long n
= strtoul (arg
, &end
, 10);
199 if (end
!= arg
+ strlen (arg
))
201 fprintf (stderr
, _("error: %s: invalid number of rounds\n"), arg
);
204 settings
.set ("build-repeat", std::to_string (std::max (0UL, n
- 1)));
207 case GUIX_OPT_IMPERSONATE_LINUX_26
:
208 settings
.impersonateLinux26
= true;
210 case GUIX_OPT_LOSE_LOGS
:
211 settings
.keepLog
= false;
213 case GUIX_OPT_LISTEN
:
216 settings
.nixDaemonSocketFile
= canonPath (arg
);
218 catch (std::exception
&e
)
220 fprintf (stderr
, _("error: %s\n"), e
.what ());
224 case GUIX_OPT_SUBSTITUTE_URLS
:
225 settings
.set ("substitute-urls", arg
);
227 case GUIX_OPT_NO_SUBSTITUTES
:
228 settings
.set ("build-use-substitutes", "false");
230 case GUIX_OPT_NO_BUILD_HOOK
:
231 settings
.useBuildHook
= false;
234 verbosity
= lvlDebug
;
236 case GUIX_OPT_GC_KEEP_OUTPUTS
:
237 settings
.gcKeepOutputs
= string_to_bool (arg
);
239 case GUIX_OPT_GC_KEEP_DERIVATIONS
:
240 settings
.gcKeepDerivations
= string_to_bool (arg
);
243 settings
.set ("build-cores", arg
);
246 settings
.set ("build-max-jobs", arg
);
248 case GUIX_OPT_SYSTEM
:
249 settings
.thisSystem
= arg
;
252 return (error_t
) ARGP_ERR_UNKNOWN
;
258 /* Argument parsing. */
259 static const struct argp argp
=
263 NULL
, NULL
, // children and help_filter
270 main (int argc
, char *argv
[])
272 static const Strings nothing
;
274 setlocale (LC_ALL
, "");
275 bindtextdomain (guix_textdomain
, LOCALEDIR
);
276 textdomain (guix_textdomain
);
278 /* Initialize libgcrypt. */
279 if (!gcry_check_version (GCRYPT_VERSION
))
281 fprintf (stderr
, _("error: libgcrypt version mismatch\n"));
285 /* Tell Libgcrypt that initialization has completed, as per the Libgcrypt
286 1.6.0 manual (although this does not appear to be strictly needed.) */
287 gcry_control (GCRYCTL_INITIALIZATION_FINISHED
, 0);
289 /* Set the umask so that the daemon does not end up creating group-writable
290 files, which would lead to "suspicious ownership or permission" errors.
291 See <http://lists.gnu.org/archive/html/bug-guix/2013-07/msg00033.html>. */
292 umask (S_IWGRP
| S_IWOTH
);
295 # error chroot is assumed to be available
298 /* Always use chroots by default. */
299 settings
.useChroot
= true;
301 /* Turn automatic deduplication on by default. */
302 settings
.autoOptimiseStore
= true;
304 /* Default to using as many cores as possible. */
305 settings
.buildCores
= 0;
311 settings
.processEnvironment ();
313 /* Hackily help 'local-store.cc' find our 'guix-authenticate' program, which
314 is known as 'OPENSSL_PATH' here. */
315 std::string search_path
;
316 search_path
= settings
.nixLibexecDir
;
317 if (getenv ("PATH") != NULL
)
320 search_path
+= getenv ("PATH");
323 setenv ("PATH", search_path
.c_str (), 1);
325 /* Use our substituter by default. */
326 settings
.substituters
.clear ();
327 settings
.set ("build-use-substitutes", "true");
329 /* Use our substitute server by default. */
330 settings
.set ("substitute-urls", GUIX_SUBSTITUTE_URLS
);
332 #ifdef HAVE_DAEMON_OFFLOAD_HOOK
333 /* Use our build hook for distributed builds by default. */
334 settings
.useBuildHook
= true;
335 if (getenv ("NIX_BUILD_HOOK") == NULL
)
337 std::string build_hook
;
339 build_hook
= settings
.nixLibexecDir
+ "/guix/offload";
340 setenv ("NIX_BUILD_HOOK", build_hook
.c_str (), 1);
343 /* We are not installing any build hook, so disable it. */
344 settings
.useBuildHook
= false;
347 argp_parse (&argp
, argc
, argv
, 0, 0, 0);
349 /* Effect all the changes made via 'settings.set'. */
352 if (settings
.useSubstitutes
)
354 string subs
= getEnv ("NIX_SUBSTITUTERS", "default");
356 if (subs
== "default")
359 settings
.nixLibexecDir
+ "/guix/substitute";
360 setenv ("NIX_SUBSTITUTERS", subst
.c_str (), 1);
364 /* Clear the substituter list to make sure nothing ever gets
365 substituted, regardless of the client's settings. */
366 setenv ("NIX_SUBSTITUTERS", "", 1);
368 /* Effect the $NIX_SUBSTITUTERS change. */
371 if (geteuid () == 0 && settings
.buildUsersGroup
.empty ())
372 fprintf (stderr
, _("warning: daemon is running as root, so \
373 using `--build-users-group' is highly recommended\n"));
375 if (settings
.useChroot
)
377 std::string chroot_dirs
;
379 chroot_dirs
= settings
.get ("build-extra-chroot-dirs",
382 format ("extra chroot directories: '%1%'") % chroot_dirs
);
386 format ("automatic deduplication set to %1%")
387 % settings
.autoOptimiseStore
);
390 format ("listening on `%1%'") % settings
.nixDaemonSocketFile
);
394 catch (std::exception
&e
)
396 fprintf (stderr
, _("error: %s\n"), e
.what ());
400 return EXIT_SUCCESS
; /* never reached */