sapling/eden/fs/service/EdenInit.cpp
Chad Austin 4b47257165 remove EdenConfig accessors
Summary:
Instead of having accessors for every config setting in EdenConfig,
just expose the ConfigSettings directly.

Reviewed By: fanzeyi

Differential Revision: D17847805

fbshipit-source-id: 8c6c1010c010113cf859677449797ea916f2a2a5
2019-10-11 17:55:19 -07:00

155 lines
4.6 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/service/EdenInit.h"
#include <boost/filesystem.hpp>
#include "eden/fs/config/EdenConfig.h"
#include "eden/fs/eden-config.h"
#include "eden/fs/fuse/privhelper/UserInfo.h"
#include "eden/fs/utils/PathFuncs.h"
using folly::StringPiece;
DEFINE_string(configPath, "", "The path of the ~/.edenrc config file");
DEFINE_string(edenDir, "", "The path to the .eden directory");
DEFINE_string(
etcEdenDir,
EDEN_ETC_EDEN_DIR,
"The directory holding all system configuration files");
DEFINE_string(
logPath,
"",
"If set, redirects stdout and stderr to the log file given.");
namespace {
using namespace facebook::eden;
constexpr StringPiece kDefaultUserConfigFile{".edenrc"};
constexpr StringPiece kEdenfsConfigFile{"edenfs.rc"};
void findEdenDir(EdenConfig& config) {
// Get the initial path to the Eden directory.
// We use the --edenDir flag if set, otherwise the value loaded from the
// config file.
boost::filesystem::path boostPath(
FLAGS_edenDir.empty() ? config.edenDir.getValue().value()
: FLAGS_edenDir);
try {
// Ensure that the directory exists, and then canonicalize its name with
// realpath(). Using realpath() requires that the directory exist.
boost::filesystem::create_directories(boostPath);
auto resolvedDir = facebook::eden::realpath(boostPath.string());
// Updating the value in the config using ConfigSource::CommandLine also
// makes sure that any future updates to the config file do not affect the
// value we use. Once we start we want to always use a fixed location for
// the eden directory.
config.edenDir.setValue(resolvedDir, ConfigSource::CommandLine);
} catch (const std::exception& ex) {
throw ArgumentError(
"error creating ", boostPath.string(), ": ", folly::exceptionStr(ex));
}
}
} // namespace
namespace facebook {
namespace eden {
DEFINE_bool(
foreground,
false,
"Run edenfs in the foreground, rather than daemonizing "
"as a background process");
PathComponentPiece getDefaultLogFileName() {
return "edenfs.log"_pc;
}
AbsolutePath makeDefaultLogDirectory(AbsolutePathPiece edenDir) {
auto logDir = edenDir + "logs"_pc;
ensureDirectoryExists(logDir);
return logDir;
}
std::string getLogPath(AbsolutePathPiece edenDir) {
// If a log path was explicitly specified as a command line argument use that
if (!FLAGS_logPath.empty()) {
return FLAGS_logPath;
}
// If we are running in the foreground default to an empty log path
// (just log directly to stderr)
if (FLAGS_foreground) {
return "";
}
auto logDir = makeDefaultLogDirectory(edenDir);
return (logDir + getDefaultLogFileName()).value();
}
std::unique_ptr<EdenConfig> getEdenConfig(UserInfo& identity) {
// normalizeBestEffort() to try resolving symlinks in these paths but don't
// fail if they don't exist.
AbsolutePath systemConfigDir;
try {
systemConfigDir = normalizeBestEffort(FLAGS_etcEdenDir);
} catch (const std::exception& ex) {
throw ArgumentError(
"invalid flag value: ",
FLAGS_etcEdenDir,
": ",
folly::exceptionStr(ex));
}
const auto systemConfigPath =
systemConfigDir + PathComponentPiece{kEdenfsConfigFile};
const std::string configPathStr = FLAGS_configPath;
AbsolutePath userConfigPath;
if (configPathStr.empty()) {
userConfigPath = identity.getHomeDirectory() +
PathComponentPiece{kDefaultUserConfigFile};
} else {
try {
userConfigPath = normalizeBestEffort(configPathStr);
} catch (const std::exception& ex) {
throw ArgumentError(
"invalid flag value: ",
FLAGS_configPath,
": ",
folly::exceptionStr(ex));
}
}
// Create the default EdenConfig. Next, update with command line arguments.
// Command line arguments will take precedence over config file settings.
auto edenConfig = std::make_unique<EdenConfig>(
identity.getUsername(),
identity.getUid(),
identity.getHomeDirectory(),
userConfigPath,
systemConfigDir,
systemConfigPath);
// Load system and user configurations
edenConfig->loadSystemConfig();
edenConfig->loadUserConfig();
// Determine the location of the Eden state directory, and update this value
// in the EdenConfig object. This also creates the directory if it does not
// exist.
findEdenDir(*edenConfig);
return edenConfig;
}
} // namespace eden
} // namespace facebook