diff options
Diffstat (limited to 'src/libstore/globals.cc')
-rw-r--r-- | src/libstore/globals.cc | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc new file mode 100644 index 000000000000..c5abeee282a3 --- /dev/null +++ b/src/libstore/globals.cc @@ -0,0 +1,274 @@ +#include "config.h" + +#include "globals.hh" +#include "util.hh" +#include "archive.hh" + +#include <map> +#include <algorithm> +#include <unistd.h> + + +namespace nix { + + +/* The default location of the daemon socket, relative to nixStateDir. + The socket is in a directory to allow you to control access to the + Nix daemon by setting the mode/ownership of the directory + appropriately. (This wouldn't work on the socket itself since it + must be deleted and recreated on startup.) */ +#define DEFAULT_SOCKET_PATH "/daemon-socket/socket" + + +Settings settings; + + +Settings::Settings() +{ + keepFailed = false; + keepGoing = false; + tryFallback = false; + buildVerbosity = lvlError; + maxBuildJobs = 1; + buildCores = 1; +#ifdef _SC_NPROCESSORS_ONLN + long res = sysconf(_SC_NPROCESSORS_ONLN); + if (res > 0) buildCores = res; +#endif + readOnlyMode = false; + thisSystem = SYSTEM; + maxSilentTime = 0; + buildTimeout = 0; + useBuildHook = true; + printBuildTrace = false; + reservedSize = 1024 * 1024; + fsyncMetadata = true; + useSQLiteWAL = true; + syncBeforeRegistering = false; + useSubstitutes = true; + buildUsersGroup = getuid() == 0 ? "nixbld" : ""; + useChroot = false; + useSshSubstituter = true; + impersonateLinux26 = false; + keepLog = true; + compressLog = true; + maxLogSize = 0; + cacheFailure = false; + pollInterval = 5; + checkRootReachability = false; + gcKeepOutputs = false; + gcKeepDerivations = true; + autoOptimiseStore = false; + envKeepDerivations = false; + lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1"; + showTrace = false; + enableImportNative = false; +} + + +void Settings::processEnvironment() +{ + nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR))); + nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR)); + nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR)); + nixStateDir = canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR)); + nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db"); + nixConfDir = canonPath(getEnv("NIX_CONF_DIR", NIX_CONF_DIR)); + nixLibexecDir = canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR)); + nixBinDir = canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR)); + nixDaemonSocketFile = canonPath(nixStateDir + DEFAULT_SOCKET_PATH); +} + + +void Settings::loadConfFile() +{ + Path settingsFile = (format("%1%/%2%") % nixConfDir % "nix.conf").str(); + if (!pathExists(settingsFile)) return; + string contents = readFile(settingsFile); + + unsigned int pos = 0; + + while (pos < contents.size()) { + string line; + while (pos < contents.size() && contents[pos] != '\n') + line += contents[pos++]; + pos++; + + string::size_type hash = line.find('#'); + if (hash != string::npos) + line = string(line, 0, hash); + + vector<string> tokens = tokenizeString<vector<string> >(line); + if (tokens.empty()) continue; + + if (tokens.size() < 2 || tokens[1] != "=") + throw Error(format("illegal configuration line ‘%1%’ in ‘%2%’") % line % settingsFile); + + string name = tokens[0]; + + vector<string>::iterator i = tokens.begin(); + advance(i, 2); + settings[name] = concatStringsSep(" ", Strings(i, tokens.end())); // FIXME: slow + }; +} + + +void Settings::set(const string & name, const string & value) +{ + settings[name] = value; + overrides[name] = value; +} + + +string Settings::get(const string & name, const string & def) +{ + auto i = settings.find(name); + if (i == settings.end()) return def; + return i->second; +} + + +Strings Settings::get(const string & name, const Strings & def) +{ + auto i = settings.find(name); + if (i == settings.end()) return def; + return tokenizeString<Strings>(i->second); +} + + +bool Settings::get(const string & name, bool def) +{ + bool res = def; + _get(res, name); + return res; +} + + +void Settings::update() +{ + _get(tryFallback, "build-fallback"); + _get(maxBuildJobs, "build-max-jobs"); + _get(buildCores, "build-cores"); + _get(thisSystem, "system"); + _get(maxSilentTime, "build-max-silent-time"); + _get(buildTimeout, "build-timeout"); + _get(reservedSize, "gc-reserved-space"); + _get(fsyncMetadata, "fsync-metadata"); + _get(useSQLiteWAL, "use-sqlite-wal"); + _get(syncBeforeRegistering, "sync-before-registering"); + _get(useSubstitutes, "build-use-substitutes"); + _get(buildUsersGroup, "build-users-group"); + _get(useChroot, "build-use-chroot"); + _get(impersonateLinux26, "build-impersonate-linux-26"); + _get(keepLog, "build-keep-log"); + _get(compressLog, "build-compress-log"); + _get(maxLogSize, "build-max-log-size"); + _get(cacheFailure, "build-cache-failure"); + _get(pollInterval, "build-poll-interval"); + _get(checkRootReachability, "gc-check-reachability"); + _get(gcKeepOutputs, "gc-keep-outputs"); + _get(gcKeepDerivations, "gc-keep-derivations"); + _get(autoOptimiseStore, "auto-optimise-store"); + _get(envKeepDerivations, "env-keep-derivations"); + _get(sshSubstituterHosts, "ssh-substituter-hosts"); + _get(useSshSubstituter, "use-ssh-substituter"); + _get(logServers, "log-servers"); + _get(enableImportNative, "allow-unsafe-native-code-during-evaluation"); + _get(useCaseHack, "use-case-hack"); + + string subs = getEnv("NIX_SUBSTITUTERS", "default"); + if (subs == "default") { + substituters.clear(); +#if 0 + if (getEnv("NIX_OTHER_STORES") != "") + substituters.push_back(nixLibexecDir + "/nix/substituters/copy-from-other-stores.pl"); +#endif + substituters.push_back(nixLibexecDir + "/nix/substituters/download-using-manifests.pl"); + substituters.push_back(nixLibexecDir + "/nix/substituters/download-from-binary-cache.pl"); + if (useSshSubstituter && !sshSubstituterHosts.empty()) + substituters.push_back(nixLibexecDir + "/nix/substituters/download-via-ssh"); + } else + substituters = tokenizeString<Strings>(subs, ":"); +} + + +void Settings::_get(string & res, const string & name) +{ + SettingsMap::iterator i = settings.find(name); + if (i == settings.end()) return; + res = i->second; +} + + +void Settings::_get(bool & res, const string & name) +{ + SettingsMap::iterator i = settings.find(name); + if (i == settings.end()) return; + if (i->second == "true") res = true; + else if (i->second == "false") res = false; + else throw Error(format("configuration option ‘%1%’ should be either ‘true’ or ‘false’, not ‘%2%’") + % name % i->second); +} + + +void Settings::_get(StringSet & res, const string & name) +{ + SettingsMap::iterator i = settings.find(name); + if (i == settings.end()) return; + res.clear(); + Strings ss = tokenizeString<Strings>(i->second); + res.insert(ss.begin(), ss.end()); +} + +void Settings::_get(Strings & res, const string & name) +{ + SettingsMap::iterator i = settings.find(name); + if (i == settings.end()) return; + res = tokenizeString<Strings>(i->second); +} + + +template<class N> void Settings::_get(N & res, const string & name) +{ + SettingsMap::iterator i = settings.find(name); + if (i == settings.end()) return; + if (!string2Int(i->second, res)) + throw Error(format("configuration setting ‘%1%’ should have an integer value") % name); +} + + +string Settings::pack() +{ + string s; + foreach (SettingsMap::iterator, i, settings) { + if (i->first.find('\n') != string::npos || + i->first.find('=') != string::npos || + i->second.find('\n') != string::npos) + throw Error("illegal option name/value"); + s += i->first; s += '='; s += i->second; s += '\n'; + } + return s; +} + + +void Settings::unpack(const string & pack) { + Strings lines = tokenizeString<Strings>(pack, "\n"); + foreach (Strings::iterator, i, lines) { + string::size_type eq = i->find('='); + if (eq == string::npos) + throw Error("illegal option name/value"); + set(i->substr(0, eq), i->substr(eq + 1)); + } +} + + +Settings::SettingsMap Settings::getOverrides() +{ + return overrides; +} + + +const string nixVersion = PACKAGE_VERSION; + + +} |