forked from lix-project/lix
parent
a0d1d0321e
commit
224157deb6
|
@ -1,14 +1,27 @@
|
|||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "command.hh"
|
||||
#include "eval-settings.hh"
|
||||
#include "eval.hh"
|
||||
#include "filetransfer.hh"
|
||||
#include "logging.hh"
|
||||
#include "serve-protocol.hh"
|
||||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
#include "split.hh"
|
||||
#include "local-fs-store.hh"
|
||||
#include "util.hh"
|
||||
#include "worker-protocol.hh"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
using namespace nix;
|
||||
|
||||
namespace {
|
||||
|
@ -61,6 +74,36 @@ struct CmdDoctor : StoreCommand
|
|||
void run(ref<Store> store) override
|
||||
{
|
||||
logger->log("Running checks against store uri: " + store->getUri());
|
||||
std::cout << "- system: " << evalSettings.getCurrentSystem() << "\n";
|
||||
|
||||
if (fs::exists("/etc/os-release")) {
|
||||
std::string hostOs = this->getOsDescription();
|
||||
std::cout << "- host os: " << hostOs << "\n";
|
||||
}
|
||||
|
||||
// Now check if multi-user.
|
||||
// FIXME: how actually do we check this?
|
||||
bool isMultiUser = settings.buildUsersGroup != "" || store->getUri() == "daemon";
|
||||
std::cout << "- multi-user?: " << (isMultiUser ? "yes" : "no") << "\n";
|
||||
std::cout << "- sandbox: " << settings.sandboxMode.to_string() << "\n";
|
||||
std::cout << "- version: ";
|
||||
// FIXME: nix-env is what nix-info uses. Is there any reason for us to do the same?
|
||||
try {
|
||||
// XXX
|
||||
printVersion("nix-env:");
|
||||
} catch (Exit const &) {
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
std::cout << "- <nixpkgs>: ";
|
||||
evalSettings.pureEval = false;
|
||||
fileTransferSettings.tries = 0; // FIXME
|
||||
EvalState evalState(SearchPath{}, store);
|
||||
auto *nixpkgsSearch = evalState.parseExprFromString("<nixpkgs>", CanonPath::fromCwd());
|
||||
Value nixpkgsValue;
|
||||
evalState.eval(nixpkgsSearch, nixpkgsValue);
|
||||
//evalState.forceValue(nixpkgsValue, noPos);
|
||||
std::cout << printValue(evalState, nixpkgsValue) << "\n";
|
||||
|
||||
if (store.dynamic_pointer_cast<LocalFSStore>()) {
|
||||
success &= checkNixInPath();
|
||||
|
@ -73,6 +116,80 @@ struct CmdDoctor : StoreCommand
|
|||
throw Exit(2);
|
||||
}
|
||||
|
||||
std::string getOsDescription() const
|
||||
{
|
||||
constexpr std::string_view NAME = "NAME=";
|
||||
constexpr std::string_view VERSION = "VERSION=";
|
||||
constexpr std::string_view PRETTY_NAME = "PRETTY_NAME=";
|
||||
constexpr std::string_view BUILD_ID = "BUILD_ID=";
|
||||
|
||||
constexpr auto dequoteStrip = [](std::string_view s) -> std::string_view {
|
||||
return stripChars(s, "\" \n\r");
|
||||
};
|
||||
|
||||
std::vector<std::string> parts;
|
||||
parts.reserve(4);
|
||||
|
||||
if (auto unameCmd = which("uname")) {
|
||||
assert(fs::path(*unameCmd).is_absolute());
|
||||
try {
|
||||
// -sr -> --kernel-name --kernel-release
|
||||
auto unameOutput = runProgram(*unameCmd, false, {"-sr"});
|
||||
parts.emplace_back(trim(unameOutput));
|
||||
} catch (ExecError const & e) {
|
||||
printError("could not run uname to get OS info: %s", e.what());
|
||||
}
|
||||
} else {
|
||||
printError("could not get OS info: uname not found in PATH");
|
||||
}
|
||||
|
||||
std::optional<std::string> name;
|
||||
std::optional<std::string> version;
|
||||
std::optional<std::string> prettyName;
|
||||
std::optional<std::string> buildId;
|
||||
|
||||
try {
|
||||
std::string const contents = readFile("/etc/os-release");
|
||||
|
||||
for (std::string_view const line : splitBy(contents, "\n")) {
|
||||
if (line.starts_with(NAME)) {
|
||||
name = dequoteStrip(line.substr(NAME.size()));
|
||||
}
|
||||
|
||||
if (line.starts_with(VERSION)) {
|
||||
version = dequoteStrip(line.substr(VERSION.size()));
|
||||
}
|
||||
|
||||
if (line.starts_with(PRETTY_NAME)) {
|
||||
prettyName = dequoteStrip(line.substr(PRETTY_NAME.size()));
|
||||
}
|
||||
|
||||
if (line.starts_with(BUILD_ID)) {
|
||||
buildId = dequoteStrip(line.substr(BUILD_ID.size()));
|
||||
}
|
||||
}
|
||||
|
||||
// Use pretty name, falling back to name and version.
|
||||
if (prettyName.has_value()) {
|
||||
parts.emplace_back(*prettyName);
|
||||
} else if (name.has_value()) {
|
||||
parts.emplace_back(*name);
|
||||
if (version.has_value()) {
|
||||
parts.emplace_back(*version);
|
||||
}
|
||||
}
|
||||
|
||||
if (buildId.has_value()) {
|
||||
parts.emplace_back(*buildId);
|
||||
}
|
||||
|
||||
} catch (SysError const & e) {
|
||||
printError("could not determine OS from /etc/os-release: %s", e.what());
|
||||
}
|
||||
|
||||
return boost::algorithm::join(parts, ", ");
|
||||
}
|
||||
|
||||
bool checkNixInPath()
|
||||
{
|
||||
PathSet dirs;
|
||||
|
|
Loading…
Reference in a new issue