mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 00:39:37 +01:00
Merge remote-tracking branch 'origin/2.26-maintenance' into detsys-main
This commit is contained in:
commit
6749d26dbb
59 changed files with 708 additions and 403 deletions
|
|
@ -64,14 +64,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
(lib.mesonEnable "markdown" enableMarkdown)
|
||||
(lib.mesonOption "readline-flavor" readlineFlavor)
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nix-expr
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -40,14 +40,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -46,14 +46,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ Strings EvalSettings::getDefaultNixPath()
|
|||
{
|
||||
Strings res;
|
||||
auto add = [&](const Path & p, const std::string & s = std::string()) {
|
||||
if (pathAccessible(p)) {
|
||||
if (std::filesystem::exists(p)) {
|
||||
if (s.empty()) {
|
||||
res.push_back(p);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3070,8 +3070,11 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
|
|||
auto i = lookupPathResolved.find(value);
|
||||
if (i != lookupPathResolved.end()) return i->second;
|
||||
|
||||
auto finish = [&](SourcePath res) {
|
||||
debug("resolved search path element '%s' to '%s'", value, res);
|
||||
auto finish = [&](std::optional<SourcePath> res) {
|
||||
if (res)
|
||||
debug("resolved search path element '%s' to '%s'", value, *res);
|
||||
else
|
||||
debug("failed to resolve search path element '%s'", value);
|
||||
lookupPathResolved.emplace(value, res);
|
||||
return res;
|
||||
};
|
||||
|
|
@ -3123,8 +3126,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
|
|||
}
|
||||
}
|
||||
|
||||
debug("failed to resolve search path element '%s'", value);
|
||||
return std::nullopt;
|
||||
return finish(std::nullopt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,14 +77,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
] ++ lib.optional enableGC boehmgc;
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
(lib.mesonEnable "gc" enableGC)
|
||||
];
|
||||
|
|
|
|||
|
|
@ -44,14 +44,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -41,14 +41,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,14 +38,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nix-flake
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -46,14 +46,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -40,14 +40,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,14 +40,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nix-main
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
openssl
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -315,20 +315,6 @@ void printVersion(const std::string & programName)
|
|||
throw Exit();
|
||||
}
|
||||
|
||||
|
||||
void showManPage(const std::string & name)
|
||||
{
|
||||
restoreProcessContext();
|
||||
setEnv("MANPATH", settings.nixManDir.c_str());
|
||||
execlp("man", "man", name.c_str(), nullptr);
|
||||
if (errno == ENOENT) {
|
||||
// Not SysError because we don't want to suffix the errno, aka No such file or directory.
|
||||
throw Error("The '%1%' command was not found, but it is needed for '%2%' and some other '%3%' commands' help text. Perhaps you could install the '%1%' command?", "man", name.c_str(), "nix-*");
|
||||
}
|
||||
throw SysError("command 'man %1%' failed", name.c_str());
|
||||
}
|
||||
|
||||
|
||||
int handleExceptions(const std::string & programName, std::function<void()> fun)
|
||||
{
|
||||
ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this
|
||||
|
|
|
|||
|
|
@ -70,11 +70,6 @@ struct LegacyArgs : public MixCommonArgs, public RootArgs
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the manual page for the specified program.
|
||||
*/
|
||||
void showManPage(const std::string & name);
|
||||
|
||||
/**
|
||||
* The constructor of this class starts a pager if standard output is a
|
||||
* terminal and $PAGER is set. Standard output is redirected to the
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nix-store
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -40,14 +40,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -52,14 +52,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
nix-store-test-support
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -300,6 +300,14 @@ struct curlFileTransfer : public FileTransfer
|
|||
return ((TransferItem *) userp)->readCallback(buffer, size, nitems);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x071000
|
||||
static int cloexec_callback(void *, curl_socket_t curlfd, curlsocktype purpose) {
|
||||
unix::closeOnExec(curlfd);
|
||||
vomit("cloexec set for fd %i", curlfd);
|
||||
return CURL_SOCKOPT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void init()
|
||||
{
|
||||
if (!req) req = curl_easy_init();
|
||||
|
|
@ -359,6 +367,10 @@ struct curlFileTransfer : public FileTransfer
|
|||
curl_easy_setopt(req, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x071000
|
||||
curl_easy_setopt(req, CURLOPT_SOCKOPTFUNCTION, cloexec_callback);
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(req, CURLOPT_CONNECTTIMEOUT, fileTransferSettings.connectTimeout.get());
|
||||
|
||||
curl_easy_setopt(req, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ Settings::Settings()
|
|||
, nixStateDir(canonPath(getEnvNonEmpty("NIX_STATE_DIR").value_or(NIX_STATE_DIR)))
|
||||
, nixConfDir(canonPath(getEnvNonEmpty("NIX_CONF_DIR").value_or(NIX_CONF_DIR)))
|
||||
, nixUserConfFiles(getUserConfigFiles())
|
||||
, nixManDir(canonPath(NIX_MAN_DIR))
|
||||
, nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
|
||||
{
|
||||
#ifndef _WIN32
|
||||
|
|
@ -243,7 +242,7 @@ Path Settings::getDefaultSSLCertFile()
|
|||
return "";
|
||||
}
|
||||
|
||||
const std::string nixVersion = PACKAGE_VERSION;
|
||||
std::string nixVersion = PACKAGE_VERSION;
|
||||
|
||||
const std::string determinateNixVersion = DETERMINATE_NIX_VERSION;
|
||||
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@ public:
|
|||
*/
|
||||
std::vector<Path> nixUserConfFiles;
|
||||
|
||||
/**
|
||||
* The directory where the man pages are stored.
|
||||
*/
|
||||
Path nixManDir;
|
||||
|
||||
/**
|
||||
* File name of the socket the daemon listens to.
|
||||
*/
|
||||
|
|
@ -1253,7 +1248,15 @@ void loadConfFile(AbstractConfig & config);
|
|||
// Used by the Settings constructor
|
||||
std::vector<Path> getUserConfigFiles();
|
||||
|
||||
extern const std::string nixVersion;
|
||||
/**
|
||||
* The version of Nix itself.
|
||||
*
|
||||
* This is not `const`, so that the Nix CLI can provide a more detailed version
|
||||
* number including the git revision, without having to "re-compile" the entire
|
||||
* set of Nix libraries to include that version, even when those libraries are
|
||||
* not affected by the change.
|
||||
*/
|
||||
extern std::string nixVersion;
|
||||
|
||||
extern const std::string determinateNixVersion;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,10 @@ ref<LegacySSHStore::Connection> LegacySSHStore::openConnection()
|
|||
command.push_back("--store");
|
||||
command.push_back(remoteStore.get());
|
||||
}
|
||||
conn->sshConn = master.startCommand(std::move(command));
|
||||
conn->sshConn = master.startCommand(std::move(command), std::list{extraSshArgs});
|
||||
if (connPipeSize) {
|
||||
conn->sshConn->trySetBufferSize(*connPipeSize);
|
||||
}
|
||||
conn->to = FdSink(conn->sshConn->in.get());
|
||||
conn->from = FdSource(conn->sshConn->out.get());
|
||||
|
||||
|
|
@ -100,19 +103,31 @@ std::string LegacySSHStore::getUri()
|
|||
return *uriSchemes().begin() + "://" + host;
|
||||
}
|
||||
|
||||
std::map<StorePath, UnkeyedValidPathInfo> LegacySSHStore::queryPathInfosUncached(
|
||||
const StorePathSet & paths)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
|
||||
/* No longer support missing NAR hash */
|
||||
assert(GET_PROTOCOL_MINOR(conn->remoteVersion) >= 4);
|
||||
|
||||
debug("querying remote host '%s' for info on '%s'", host, concatStringsSep(", ", printStorePathSet(paths)));
|
||||
|
||||
auto infos = conn->queryPathInfos(*this, paths);
|
||||
|
||||
for (const auto & [_, info] : infos) {
|
||||
if (info.narHash == Hash::dummy)
|
||||
throw Error("NAR hash is now mandatory");
|
||||
}
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
void LegacySSHStore::queryPathInfoUncached(const StorePath & path,
|
||||
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
|
||||
{
|
||||
try {
|
||||
auto conn(connections->get());
|
||||
|
||||
/* No longer support missing NAR hash */
|
||||
assert(GET_PROTOCOL_MINOR(conn->remoteVersion) >= 4);
|
||||
|
||||
debug("querying remote host '%s' for info on '%s'", host, printStorePath(path));
|
||||
|
||||
auto infos = conn->queryPathInfos(*this, {path});
|
||||
auto infos = queryPathInfosUncached({path});
|
||||
|
||||
switch (infos.size()) {
|
||||
case 0:
|
||||
|
|
@ -120,9 +135,6 @@ void LegacySSHStore::queryPathInfoUncached(const StorePath & path,
|
|||
case 1: {
|
||||
auto & [path2, info] = *infos.begin();
|
||||
|
||||
if (info.narHash == Hash::dummy)
|
||||
throw Error("NAR hash is now mandatory");
|
||||
|
||||
assert(path == path2);
|
||||
return callback(std::make_shared<ValidPathInfo>(
|
||||
std::move(path),
|
||||
|
|
@ -193,13 +205,19 @@ void LegacySSHStore::addToStore(const ValidPathInfo & info, Source & source,
|
|||
|
||||
void LegacySSHStore::narFromPath(const StorePath & path, Sink & sink)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
conn->narFromPath(*this, path, [&](auto & source) {
|
||||
narFromPath(path, [&](auto & source) {
|
||||
copyNAR(source, sink);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void LegacySSHStore::narFromPath(const StorePath & path, std::function<void(Source &)> fun)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
conn->narFromPath(*this, path, fun);
|
||||
}
|
||||
|
||||
|
||||
static ServeProto::BuildOptions buildSettings()
|
||||
{
|
||||
return {
|
||||
|
|
@ -223,6 +241,19 @@ BuildResult LegacySSHStore::buildDerivation(const StorePath & drvPath, const Bas
|
|||
return conn->getBuildDerivationResponse(*this);
|
||||
}
|
||||
|
||||
std::function<BuildResult()> LegacySSHStore::buildDerivationAsync(
|
||||
const StorePath & drvPath, const BasicDerivation & drv,
|
||||
const ServeProto::BuildOptions & options)
|
||||
{
|
||||
// Until we have C++23 std::move_only_function
|
||||
auto conn = std::make_shared<Pool<Connection>::Handle>(connections->get());
|
||||
(*conn)->putBuildDerivationRequest(*this, drvPath, drv, options);
|
||||
|
||||
return [this,conn]() -> BuildResult {
|
||||
return (*conn)->getBuildDerivationResponse(*this);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void LegacySSHStore::buildPaths(const std::vector<DerivedPath> & drvPaths, BuildMode buildMode, std::shared_ptr<Store> evalStore)
|
||||
{
|
||||
|
|
@ -294,6 +325,32 @@ StorePathSet LegacySSHStore::queryValidPaths(const StorePathSet & paths,
|
|||
}
|
||||
|
||||
|
||||
StorePathSet LegacySSHStore::queryValidPaths(const StorePathSet & paths,
|
||||
bool lock, SubstituteFlag maybeSubstitute)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
return conn->queryValidPaths(*this,
|
||||
lock, paths, maybeSubstitute);
|
||||
}
|
||||
|
||||
|
||||
void LegacySSHStore::addMultipleToStoreLegacy(Store & srcStore, const StorePathSet & paths)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
conn->to << ServeProto::Command::ImportPaths;
|
||||
try {
|
||||
srcStore.exportPaths(paths, conn->to);
|
||||
} catch (...) {
|
||||
conn->good = false;
|
||||
throw;
|
||||
}
|
||||
conn->to.flush();
|
||||
|
||||
if (readInt(conn->from) != 1)
|
||||
throw Error("remote machine failed to import closure");
|
||||
}
|
||||
|
||||
|
||||
void LegacySSHStore::connect()
|
||||
{
|
||||
auto conn(connections->get());
|
||||
|
|
@ -307,6 +364,28 @@ unsigned int LegacySSHStore::getProtocol()
|
|||
}
|
||||
|
||||
|
||||
pid_t LegacySSHStore::getConnectionPid()
|
||||
{
|
||||
auto conn(connections->get());
|
||||
#ifndef _WIN32
|
||||
return conn->sshConn->sshPid;
|
||||
#else
|
||||
// TODO: Implement
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
LegacySSHStore::ConnectionStats LegacySSHStore::getConnectionStats()
|
||||
{
|
||||
auto conn(connections->get());
|
||||
return {
|
||||
.bytesReceived = conn->from.read,
|
||||
.bytesSent = conn->to.written,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The legacy ssh protocol doesn't support checking for trusted-user.
|
||||
* Try using ssh-ng:// instead if you want to know.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "ssh.hh"
|
||||
#include "callback.hh"
|
||||
#include "pool.hh"
|
||||
#include "serve-protocol.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
@ -24,6 +25,16 @@ struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig
|
|||
const Setting<int> maxConnections{this, 1, "max-connections",
|
||||
"Maximum number of concurrent SSH connections."};
|
||||
|
||||
/**
|
||||
* Hack for hydra
|
||||
*/
|
||||
Strings extraSshArgs = {};
|
||||
|
||||
/**
|
||||
* Exposed for hydra
|
||||
*/
|
||||
std::optional<size_t> connPipeSize;
|
||||
|
||||
const std::string name() override { return "SSH Store"; }
|
||||
|
||||
static std::set<std::string> uriSchemes() { return {"ssh"}; }
|
||||
|
|
@ -60,11 +71,24 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
|
|||
void queryPathInfoUncached(const StorePath & path,
|
||||
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
|
||||
|
||||
std::map<StorePath, UnkeyedValidPathInfo> queryPathInfosUncached(
|
||||
const StorePathSet & paths);
|
||||
|
||||
void addToStore(const ValidPathInfo & info, Source & source,
|
||||
RepairFlag repair, CheckSigsFlag checkSigs) override;
|
||||
|
||||
void narFromPath(const StorePath & path, Sink & sink) override;
|
||||
|
||||
/**
|
||||
* Hands over the connection temporarily as source to the given
|
||||
* function. The function must not consume beyond the NAR; it can
|
||||
* not just blindly try to always read more bytes until it is
|
||||
* cut-off.
|
||||
*
|
||||
* This is exposed for sake of Hydra.
|
||||
*/
|
||||
void narFromPath(const StorePath & path, std::function<void(Source &)> fun);
|
||||
|
||||
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
|
||||
{ unsupported("queryPathFromHashPart"); }
|
||||
|
||||
|
|
@ -93,6 +117,16 @@ public:
|
|||
BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
||||
BuildMode buildMode) override;
|
||||
|
||||
/**
|
||||
* Note, the returned function must only be called once, or we'll
|
||||
* try to read from the connection twice.
|
||||
*
|
||||
* @todo Use C++23 `std::move_only_function`.
|
||||
*/
|
||||
std::function<BuildResult()> buildDerivationAsync(
|
||||
const StorePath & drvPath, const BasicDerivation & drv,
|
||||
const ServeProto::BuildOptions & options);
|
||||
|
||||
void buildPaths(const std::vector<DerivedPath> & drvPaths, BuildMode buildMode, std::shared_ptr<Store> evalStore) override;
|
||||
|
||||
void ensurePath(const StorePath & path) override
|
||||
|
|
@ -119,10 +153,36 @@ public:
|
|||
StorePathSet queryValidPaths(const StorePathSet & paths,
|
||||
SubstituteFlag maybeSubstitute = NoSubstitute) override;
|
||||
|
||||
/**
|
||||
* Custom variation that atomically creates temp locks on the remote
|
||||
* side.
|
||||
*
|
||||
* This exists to prevent a race where the remote host
|
||||
* garbage-collects paths that are already there. Optionally, ask
|
||||
* the remote host to substitute missing paths.
|
||||
*/
|
||||
StorePathSet queryValidPaths(const StorePathSet & paths,
|
||||
bool lock,
|
||||
SubstituteFlag maybeSubstitute = NoSubstitute);
|
||||
|
||||
/**
|
||||
* Just exists because this is exactly what Hydra was doing, and we
|
||||
* don't yet want an algorithmic change.
|
||||
*/
|
||||
void addMultipleToStoreLegacy(Store & srcStore, const StorePathSet & paths);
|
||||
|
||||
void connect() override;
|
||||
|
||||
unsigned int getProtocol() override;
|
||||
|
||||
struct ConnectionStats {
|
||||
size_t bytesReceived, bytesSent;
|
||||
};
|
||||
|
||||
ConnectionStats getConnectionStats();
|
||||
|
||||
pid_t getConnectionPid();
|
||||
|
||||
/**
|
||||
* The legacy ssh protocol doesn't support checking for trusted-user.
|
||||
* Try using ssh-ng:// instead if you want to know.
|
||||
|
|
|
|||
|
|
@ -136,7 +136,12 @@ LocalStore::LocalStore(
|
|||
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
|
||||
createDirs(perUserDir);
|
||||
if (!readOnly) {
|
||||
if (chmod(perUserDir.c_str(), 0755) == -1)
|
||||
auto st = lstat(perUserDir);
|
||||
|
||||
// Skip chmod call if the directory already has the correct permissions (0755).
|
||||
// This is to avoid failing when the executing user lacks permissions to change the directory's permissions
|
||||
// even if it would be no-op.
|
||||
if ((st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != 0755 && chmod(perUserDir.c_str(), 0755) == -1)
|
||||
throw SysError("could not set permissions on '%s' to 755", perUserDir);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,14 +71,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags =
|
||||
[
|
||||
(lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux)
|
||||
|
|
|
|||
|
|
@ -240,4 +240,19 @@ Path SSHMaster::startMaster()
|
|||
|
||||
#endif
|
||||
|
||||
void SSHMaster::Connection::trySetBufferSize(size_t size)
|
||||
{
|
||||
#ifdef F_SETPIPE_SZ
|
||||
/* This `fcntl` method of doing this takes a positive `int`. Check
|
||||
and convert accordingly.
|
||||
|
||||
The function overall still takes `size_t` because this is more
|
||||
portable for a platform-agnostic interface. */
|
||||
assert(size <= INT_MAX);
|
||||
int pipesize = size;
|
||||
fcntl(in.get(), F_SETPIPE_SZ, pipesize);
|
||||
fcntl(out.get(), F_SETPIPE_SZ, pipesize);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,18 @@ public:
|
|||
Pid sshPid;
|
||||
#endif
|
||||
AutoCloseFD out, in;
|
||||
|
||||
/**
|
||||
* Try to set the buffer size in both directions to the
|
||||
* designated amount, if possible. If not possible, does
|
||||
* nothing.
|
||||
*
|
||||
* Current implementation is to use `fcntl` with `F_SETPIPE_SZ`,
|
||||
* which is Linux-only. For this implementation, `size` must
|
||||
* convertable to an `int`. In other words, it must be within
|
||||
* `[0, INT_MAX]`.
|
||||
*/
|
||||
void trySetBufferSize(size_t size);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -230,18 +230,22 @@ void Store::addMultipleToStore(
|
|||
{
|
||||
std::atomic<size_t> nrDone{0};
|
||||
std::atomic<size_t> nrFailed{0};
|
||||
std::atomic<uint64_t> bytesExpected{0};
|
||||
std::atomic<uint64_t> nrRunning{0};
|
||||
|
||||
using PathWithInfo = std::pair<ValidPathInfo, std::unique_ptr<Source>>;
|
||||
|
||||
uint64_t bytesExpected = 0;
|
||||
|
||||
std::map<StorePath, PathWithInfo *> infosMap;
|
||||
StorePathSet storePathsToAdd;
|
||||
for (auto & thingToAdd : pathsToCopy) {
|
||||
bytesExpected += thingToAdd.first.narSize;
|
||||
infosMap.insert_or_assign(thingToAdd.first.path, &thingToAdd);
|
||||
storePathsToAdd.insert(thingToAdd.first.path);
|
||||
}
|
||||
|
||||
act.setExpected(actCopyPath, bytesExpected);
|
||||
|
||||
auto showProgress = [&, nrTotal = pathsToCopy.size()]() {
|
||||
act.progress(nrDone, nrTotal, nrRunning, nrFailed);
|
||||
};
|
||||
|
|
@ -259,9 +263,6 @@ void Store::addMultipleToStore(
|
|||
return StorePathSet();
|
||||
}
|
||||
|
||||
bytesExpected += info.narSize;
|
||||
act.setExpected(actCopyPath, bytesExpected);
|
||||
|
||||
return info.references;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nix-util
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -38,14 +38,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -45,14 +45,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -52,17 +52,6 @@ mkMesonLibrary (finalAttrs: {
|
|||
nlohmann_json
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
#
|
||||
# TODO: change release process to add `pre` in `.version`, remove it
|
||||
# before tagging, and restore after.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
(lib.mesonEnable "cpuid" stdenv.hostPlatform.isx86_64)
|
||||
];
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "users.hh"
|
||||
#include "network-proxy.hh"
|
||||
#include "compatibility-settings.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
using namespace nix;
|
||||
using namespace std::string_literals;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "users.hh"
|
||||
#include "tarball.hh"
|
||||
#include "self-exe.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <regex>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "shared.hh"
|
||||
#include "globals.hh"
|
||||
#include "legacy.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "realisation.hh"
|
||||
#include "store-api.hh"
|
||||
#include "legacy.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
using namespace nix;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "legacy.hh"
|
||||
#include "eval-settings.hh" // for defexpr
|
||||
#include "terminal.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "local-fs-store.hh"
|
||||
#include "common-eval-args.hh"
|
||||
#include "legacy.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "legacy.hh"
|
||||
#include "posix-source-accessor.hh"
|
||||
#include "path-with-outputs.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#ifndef _WIN32 // TODO implement on Windows or provide allowed-to-noop interface
|
||||
# include "local-store.hh"
|
||||
|
|
|
|||
|
|
@ -1088,12 +1088,14 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
|
|||
nlohmann::json jsonObj2 = json ? json::object() : nlohmann::json(nullptr);
|
||||
for (auto & [inputName, input] : node.inputs) {
|
||||
if (auto inputNode = std::get_if<0>(&input)) {
|
||||
if ((*inputNode)->lockedRef.input.isRelative())
|
||||
continue;
|
||||
auto storePath =
|
||||
dryRun
|
||||
? (*inputNode)->lockedRef.input.computeStorePath(*store)
|
||||
: (*inputNode)->lockedRef.input.fetchToStore(store).first;
|
||||
if (json) {
|
||||
auto& jsonObj3 = jsonObj2[inputName];
|
||||
auto & jsonObj3 = jsonObj2[inputName];
|
||||
jsonObj3["path"] = store->printStorePath(storePath);
|
||||
sources.insert(std::move(storePath));
|
||||
jsonObj3["inputs"] = traverse(**inputNode);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "git.hh"
|
||||
#include "posix-source-accessor.hh"
|
||||
#include "misc-store-flags.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
using namespace nix;
|
||||
|
||||
|
|
|
|||
|
|
@ -553,6 +553,9 @@ void mainWrapped(int argc, char * * argv)
|
|||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
// The CLI has a more detailed version than the libraries; see nixVersion.
|
||||
nix::nixVersion = NIX_CLI_VERSION;
|
||||
|
||||
// Increase the default stack size for the evaluator and for
|
||||
// libstdc++'s std::regex.
|
||||
nix::setStackSize(64 * 1024 * 1024);
|
||||
|
|
|
|||
29
src/nix/man-pages.cc
Normal file
29
src/nix/man-pages.cc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "man-pages.hh"
|
||||
#include "file-system.hh"
|
||||
#include "current-process.hh"
|
||||
#include "environment-variables.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::filesystem::path getNixManDir()
|
||||
{
|
||||
return canonPath(NIX_MAN_DIR);
|
||||
}
|
||||
|
||||
void showManPage(const std::string & name)
|
||||
{
|
||||
restoreProcessContext();
|
||||
setEnv("MANPATH", (getNixManDir().string() + ":").c_str());
|
||||
execlp("man", "man", name.c_str(), nullptr);
|
||||
if (errno == ENOENT) {
|
||||
// Not SysError because we don't want to suffix the errno, aka No such file or directory.
|
||||
throw Error(
|
||||
"The '%1%' command was not found, but it is needed for '%2%' and some other '%3%' commands' help text. Perhaps you could install the '%1%' command?",
|
||||
"man",
|
||||
name.c_str(),
|
||||
"nix-*");
|
||||
}
|
||||
throw SysError("command 'man %1%' failed", name.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
28
src/nix/man-pages.hh
Normal file
28
src/nix/man-pages.hh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* @brief Get path to the nix manual dir.
|
||||
*
|
||||
* Nix relies on the man pages being available at a NIX_MAN_DIR for
|
||||
* displaying help messaged for legacy cli.
|
||||
*
|
||||
* NIX_MAN_DIR is a compile-time parameter, so man pages are unlikely to work
|
||||
* for cases when the nix executable is installed out-of-store or as a static binary.
|
||||
*
|
||||
*/
|
||||
std::filesystem::path getNixManDir();
|
||||
|
||||
/**
|
||||
* Show the manual page for the specified program.
|
||||
*
|
||||
* @param name Name of the man item.
|
||||
*/
|
||||
void showManPage(const std::string & name);
|
||||
|
||||
}
|
||||
|
|
@ -35,6 +35,9 @@ subdir('nix-meson-build-support/windows-version')
|
|||
|
||||
configdata = configuration_data()
|
||||
|
||||
# The CLI has a more detailed version string than the libraries; see `nixVersion`
|
||||
configdata.set_quoted('NIX_CLI_VERSION', meson.project_version())
|
||||
|
||||
fs = import('fs')
|
||||
|
||||
bindir = get_option('bindir')
|
||||
|
|
@ -90,6 +93,7 @@ nix_sources = [config_h] + files(
|
|||
'ls.cc',
|
||||
'main.cc',
|
||||
'make-content-addressed.cc',
|
||||
'man-pages.cc',
|
||||
'nar.cc',
|
||||
'optimise-store.cc',
|
||||
'path-from-hash-part.cc',
|
||||
|
|
@ -182,6 +186,16 @@ if host_machine.system() != 'windows'
|
|||
]
|
||||
endif
|
||||
|
||||
fs = import('fs')
|
||||
prefix = get_option('prefix')
|
||||
|
||||
mandir = get_option('mandir')
|
||||
mandir = fs.is_absolute(mandir) ? mandir : prefix / mandir
|
||||
|
||||
cpp_args= [
|
||||
'-DNIX_MAN_DIR="@0@"'.format(mandir)
|
||||
]
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
this_exe = executable(
|
||||
|
|
@ -189,6 +203,7 @@ this_exe = executable(
|
|||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
cpp_args : cpp_args,
|
||||
link_args: linker_export_flags,
|
||||
install : true,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -91,14 +91,6 @@ mkMesonExecutable (finalAttrs: {
|
|||
nix-cmd
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${version} > ../../../.version
|
||||
'';
|
||||
|
||||
mesonFlags = [
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "posix-source-accessor.hh"
|
||||
#include "misc-store-flags.hh"
|
||||
#include "terminal.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "finally.hh"
|
||||
#include "legacy.hh"
|
||||
#include "daemon.hh"
|
||||
#include "man-pages.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ StoreWrapper::computeFSClosure(int flipDirection, int includeOutputs, ...)
|
|||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
for (int n = 2; n < items; ++n)
|
||||
for (int n = 3; n < items; ++n)
|
||||
THIS->store->computeFSClosure(THIS->store->parseStorePath(SvPV_nolen(ST(n))), paths, flipDirection, includeOutputs);
|
||||
for (auto & i : paths)
|
||||
XPUSHs(sv_2mortal(newSVpv(THIS->store->printStorePath(i).c_str(), 0)));
|
||||
|
|
@ -208,7 +208,7 @@ StoreWrapper::topoSortPaths(...)
|
|||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
for (int n = 0; n < items; ++n) paths.insert(THIS->store->parseStorePath(SvPV_nolen(ST(n))));
|
||||
for (int n = 1; n < items; ++n) paths.insert(THIS->store->parseStorePath(SvPV_nolen(ST(n))));
|
||||
auto sorted = THIS->store->topoSortPaths(paths);
|
||||
for (auto & i : sorted)
|
||||
XPUSHs(sv_2mortal(newSVpv(THIS->store->printStorePath(i).c_str(), 0)));
|
||||
|
|
@ -234,7 +234,7 @@ StoreWrapper::exportPaths(int fd, ...)
|
|||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
for (int n = 1; n < items; ++n) paths.insert(THIS->store->parseStorePath(SvPV_nolen(ST(n))));
|
||||
for (int n = 2; n < items; ++n) paths.insert(THIS->store->parseStorePath(SvPV_nolen(ST(n))));
|
||||
FdSink sink(fd);
|
||||
THIS->store->exportPaths(paths, sink);
|
||||
} catch (Error & e) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue