Automatically use --no-net if there are no network interfaces

(cherry picked from commit 04a59769963fe2a28d10ba15de743fe499333c80)
This commit is contained in:
Eelco Dolstra 2019-06-17 09:57:22 +02:00
parent 5600b070a7
commit 09dde33c19
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
2 changed files with 55 additions and 11 deletions

View file

@ -1,6 +1,5 @@
#include "common-args.hh" #include "common-args.hh"
#include "globals.hh" #include "globals.hh"
#include "download.hh"
namespace nix { namespace nix {
@ -45,16 +44,6 @@ MixCommonArgs::MixCommonArgs(const string & programName)
settings.set("max-jobs", s); settings.set("max-jobs", s);
}); });
mkFlag()
.longName("no-net")
.description("disable substituters and consider all previously downloaded files up-to-date")
.handler([]() {
settings.useSubstitutes = false;
settings.tarballTtl = std::numeric_limits<unsigned int>::max();
downloadSettings.tries = 0;
downloadSettings.connectTimeout = 1;
});
std::string cat = "config"; std::string cat = "config";
globalConfig.convertToArgs(*this, cat); globalConfig.convertToArgs(*this, cat);

View file

@ -8,19 +8,52 @@
#include "shared.hh" #include "shared.hh"
#include "store-api.hh" #include "store-api.hh"
#include "progress-bar.hh" #include "progress-bar.hh"
#include "download.hh"
#include "finally.hh" #include "finally.hh"
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netdb.h>
extern std::string chrootHelperName; extern std::string chrootHelperName;
void chrootHelper(int argc, char * * argv); void chrootHelper(int argc, char * * argv);
namespace nix { namespace nix {
/* Check if we have a non-loopback/link-local network interface. */
static bool haveInternet()
{
struct ifaddrs * addrs;
if (getifaddrs(&addrs))
return true;
Finally free([&]() { freeifaddrs(addrs); });
for (auto i = addrs; i; i = i->ifa_next) {
if (!i->ifa_addr) continue;
if (i->ifa_addr->sa_family == AF_INET) {
if (ntohl(((sockaddr_in *) i->ifa_addr)->sin_addr.s_addr) != INADDR_LOOPBACK) {
return true;
}
} else if (i->ifa_addr->sa_family == AF_INET6) {
if (!IN6_IS_ADDR_LOOPBACK(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr) &&
!IN6_IS_ADDR_LINKLOCAL(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr))
return true;
}
}
return false;
}
std::string programPath; std::string programPath;
struct NixArgs : virtual MultiCommand, virtual MixCommonArgs struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{ {
bool printBuildLogs = false; bool printBuildLogs = false;
bool useNet = true;
NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix") NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
{ {
@ -53,6 +86,11 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
.longName("version") .longName("version")
.description("show version information") .description("show version information")
.handler([&]() { printVersion(programName); }); .handler([&]() { printVersion(programName); });
mkFlag()
.longName("no-net")
.description("disable substituters and consider all previously downloaded files up-to-date")
.handler([&]() { useNet = false; });
} }
void printFlags(std::ostream & out) override void printFlags(std::ostream & out) override
@ -108,6 +146,23 @@ void mainWrapped(int argc, char * * argv)
startProgressBar(args.printBuildLogs); startProgressBar(args.printBuildLogs);
if (args.useNet && !haveInternet()) {
warn("you don't have Internet access; disabling some network-dependent features");
args.useNet = false;
}
if (!args.useNet) {
// FIXME: should check for command line overrides only.
if (!settings.useSubstitutes.overriden)
settings.useSubstitutes = false;
if (!settings.tarballTtl.overriden)
settings.tarballTtl = std::numeric_limits<unsigned int>::max();
if (!downloadSettings.tries.overriden)
downloadSettings.tries = 0;
if (!downloadSettings.connectTimeout.overriden)
downloadSettings.connectTimeout = 1;
}
args.command->prepare(); args.command->prepare();
args.command->run(); args.command->run();
} }