mirror of
https://github.com/NixOS/nix
synced 2025-07-07 10:11:47 +02:00
Stores no longer inherit from their configs
Fix #10766 See that ticket for details. Progress (I hope!) towards #11139. Co-Authored-By: Sergei Zimmerman <xokdvium@proton.me>
This commit is contained in:
parent
f0f196cef0
commit
934918ba16
48 changed files with 743 additions and 593 deletions
|
@ -75,6 +75,11 @@ std::string LocalStoreConfig::doc()
|
|||
;
|
||||
}
|
||||
|
||||
ref<Store> LocalStore::Config::openStore() const
|
||||
{
|
||||
return make_ref<LocalStore>(ref{shared_from_this()});
|
||||
}
|
||||
|
||||
struct LocalStore::State::Stmts {
|
||||
/* Some precompiled SQLite statements. */
|
||||
SQLiteStmt RegisterValidPath;
|
||||
|
@ -97,38 +102,33 @@ struct LocalStore::State::Stmts {
|
|||
SQLiteStmt AddRealisationReference;
|
||||
};
|
||||
|
||||
LocalStore::LocalStore(
|
||||
std::string_view scheme,
|
||||
PathView path,
|
||||
const Params & params)
|
||||
: StoreConfig(params)
|
||||
, LocalFSStoreConfig(path, params)
|
||||
, LocalStoreConfig(scheme, path, params)
|
||||
, Store(params)
|
||||
, LocalFSStore(params)
|
||||
, dbDir(stateDir + "/db")
|
||||
, linksDir(realStoreDir + "/.links")
|
||||
LocalStore::LocalStore(ref<const Config> config)
|
||||
: Store{*config}
|
||||
, LocalFSStore{*config}
|
||||
, config{config}
|
||||
, dbDir(config->stateDir + "/db")
|
||||
, linksDir(config->realStoreDir + "/.links")
|
||||
, reservedPath(dbDir + "/reserved")
|
||||
, schemaPath(dbDir + "/schema")
|
||||
, tempRootsDir(stateDir + "/temproots")
|
||||
, tempRootsDir(config->stateDir + "/temproots")
|
||||
, fnTempRoots(fmt("%s/%d", tempRootsDir, getpid()))
|
||||
{
|
||||
auto state(_state.lock());
|
||||
state->stmts = std::make_unique<State::Stmts>();
|
||||
|
||||
/* Create missing state directories if they don't already exist. */
|
||||
createDirs(realStoreDir.get());
|
||||
if (readOnly) {
|
||||
createDirs(config->realStoreDir.get());
|
||||
if (config->readOnly) {
|
||||
experimentalFeatureSettings.require(Xp::ReadOnlyLocalStore);
|
||||
} else {
|
||||
makeStoreWritable();
|
||||
}
|
||||
createDirs(linksDir);
|
||||
Path profilesDir = stateDir + "/profiles";
|
||||
Path profilesDir = config->stateDir + "/profiles";
|
||||
createDirs(profilesDir);
|
||||
createDirs(tempRootsDir);
|
||||
createDirs(dbDir);
|
||||
Path gcRootsDir = stateDir + "/gcroots";
|
||||
Path gcRootsDir = config->stateDir + "/gcroots";
|
||||
if (!pathExists(gcRootsDir)) {
|
||||
createDirs(gcRootsDir);
|
||||
createSymlink(profilesDir, gcRootsDir + "/profiles");
|
||||
|
@ -136,7 +136,7 @@ LocalStore::LocalStore(
|
|||
|
||||
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
|
||||
createDirs(perUserDir);
|
||||
if (!readOnly) {
|
||||
if (!config->readOnly) {
|
||||
// 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.
|
||||
|
@ -153,16 +153,16 @@ LocalStore::LocalStore(
|
|||
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
||||
if (!gr)
|
||||
printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup);
|
||||
else if (!readOnly) {
|
||||
else if (!config->readOnly) {
|
||||
struct stat st;
|
||||
if (stat(realStoreDir.get().c_str(), &st))
|
||||
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
||||
if (stat(config->realStoreDir.get().c_str(), &st))
|
||||
throw SysError("getting attributes of path '%1%'", config->realStoreDir);
|
||||
|
||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
||||
if (chown(realStoreDir.get().c_str(), 0, gr->gr_gid) == -1)
|
||||
throw SysError("changing ownership of path '%1%'", realStoreDir);
|
||||
if (chmod(realStoreDir.get().c_str(), perm) == -1)
|
||||
throw SysError("changing permissions on path '%1%'", realStoreDir);
|
||||
if (chown(config->realStoreDir.get().c_str(), 0, gr->gr_gid) == -1)
|
||||
throw SysError("changing ownership of path '%1%'", config->realStoreDir);
|
||||
if (chmod(config->realStoreDir.get().c_str(), perm) == -1)
|
||||
throw SysError("changing permissions on path '%1%'", config->realStoreDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ LocalStore::LocalStore(
|
|||
|
||||
/* Ensure that the store and its parents are not symlinks. */
|
||||
if (!settings.allowSymlinkedStore) {
|
||||
std::filesystem::path path = realStoreDir.get();
|
||||
std::filesystem::path path = config->realStoreDir.get();
|
||||
std::filesystem::path root = path.root_path();
|
||||
while (path != root) {
|
||||
if (std::filesystem::is_symlink(path))
|
||||
|
@ -217,12 +217,12 @@ LocalStore::LocalStore(
|
|||
|
||||
/* Acquire the big fat lock in shared mode to make sure that no
|
||||
schema upgrade is in progress. */
|
||||
if (!readOnly) {
|
||||
if (!config->readOnly) {
|
||||
Path globalLockPath = dbDir + "/big-lock";
|
||||
globalLock = openLockFile(globalLockPath.c_str(), true);
|
||||
}
|
||||
|
||||
if (!readOnly && !lockFile(globalLock.get(), ltRead, false)) {
|
||||
if (!config->readOnly && !lockFile(globalLock.get(), ltRead, false)) {
|
||||
printInfo("waiting for the big Nix store lock...");
|
||||
lockFile(globalLock.get(), ltRead, true);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ LocalStore::LocalStore(
|
|||
/* Check the current database schema and if necessary do an
|
||||
upgrade. */
|
||||
int curSchema = getSchema();
|
||||
if (readOnly && curSchema < nixSchemaVersion) {
|
||||
if (config->readOnly && curSchema < nixSchemaVersion) {
|
||||
debug("current schema version: %d", curSchema);
|
||||
debug("supported schema version: %d", nixSchemaVersion);
|
||||
throw Error(curSchema == 0 ?
|
||||
|
@ -378,15 +378,9 @@ LocalStore::LocalStore(
|
|||
}
|
||||
|
||||
|
||||
LocalStore::LocalStore(const Params & params)
|
||||
: LocalStore("local", "", params)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AutoCloseFD LocalStore::openGCLock()
|
||||
{
|
||||
Path fnGCLock = stateDir + "/gc.lock";
|
||||
Path fnGCLock = config->stateDir + "/gc.lock";
|
||||
auto fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT
|
||||
#ifndef _WIN32
|
||||
| O_CLOEXEC
|
||||
|
@ -452,17 +446,17 @@ int LocalStore::getSchema()
|
|||
|
||||
void LocalStore::openDB(State & state, bool create)
|
||||
{
|
||||
if (create && readOnly) {
|
||||
if (create && config->readOnly) {
|
||||
throw Error("cannot create database while in read-only mode");
|
||||
}
|
||||
|
||||
if (access(dbDir.c_str(), R_OK | (readOnly ? 0 : W_OK)))
|
||||
if (access(dbDir.c_str(), R_OK | (config->readOnly ? 0 : W_OK)))
|
||||
throw SysError("Nix database directory '%1%' is not writable", dbDir);
|
||||
|
||||
/* Open the Nix database. */
|
||||
std::string dbPath = dbDir + "/db.sqlite";
|
||||
auto & db(state.db);
|
||||
auto openMode = readOnly ? SQLiteOpenMode::Immutable
|
||||
auto openMode = config->readOnly ? SQLiteOpenMode::Immutable
|
||||
: create ? SQLiteOpenMode::Normal
|
||||
: SQLiteOpenMode::NoCreate;
|
||||
state.db = SQLite(dbPath, openMode);
|
||||
|
@ -575,12 +569,12 @@ void LocalStore::makeStoreWritable()
|
|||
if (!isRootUser()) return;
|
||||
/* Check if /nix/store is on a read-only mount. */
|
||||
struct statvfs stat;
|
||||
if (statvfs(realStoreDir.get().c_str(), &stat) != 0)
|
||||
if (statvfs(config->realStoreDir.get().c_str(), &stat) != 0)
|
||||
throw SysError("getting info about the Nix store mount point");
|
||||
|
||||
if (stat.f_flag & ST_RDONLY) {
|
||||
if (mount(0, realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError("remounting %1% writable", realStoreDir);
|
||||
if (mount(0, config->realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError("remounting %1% writable", config->realStoreDir);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -920,7 +914,7 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths)
|
|||
for (auto & sub : getDefaultSubstituters()) {
|
||||
if (remaining.empty()) break;
|
||||
if (sub->storeDir != storeDir) continue;
|
||||
if (!sub->wantMassQuery) continue;
|
||||
if (!sub->config.wantMassQuery) continue;
|
||||
|
||||
auto valid = sub->queryValidPaths(remaining);
|
||||
|
||||
|
@ -1032,12 +1026,12 @@ const PublicKeys & LocalStore::getPublicKeys()
|
|||
|
||||
bool LocalStore::pathInfoIsUntrusted(const ValidPathInfo & info)
|
||||
{
|
||||
return requireSigs && !info.checkSignatures(*this, getPublicKeys());
|
||||
return config->requireSigs && !info.checkSignatures(*this, getPublicKeys());
|
||||
}
|
||||
|
||||
bool LocalStore::realisationIsUntrusted(const Realisation & realisation)
|
||||
{
|
||||
return requireSigs && !realisation.checkSignatures(getPublicKeys());
|
||||
return config->requireSigs && !realisation.checkSignatures(getPublicKeys());
|
||||
}
|
||||
|
||||
void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
|
||||
|
@ -1334,7 +1328,7 @@ std::pair<std::filesystem::path, AutoCloseFD> LocalStore::createTempDirInStore()
|
|||
/* There is a slight possibility that `tmpDir' gets deleted by
|
||||
the GC between createTempDir() and when we acquire a lock on it.
|
||||
We'll repeat until 'tmpDir' exists and we've locked it. */
|
||||
tmpDirFn = createTempDir(realStoreDir, "tmp");
|
||||
tmpDirFn = createTempDir(config->realStoreDir, "tmp");
|
||||
tmpDirFd = openDirectory(tmpDirFn);
|
||||
if (!tmpDirFd) {
|
||||
continue;
|
||||
|
@ -1475,7 +1469,7 @@ LocalStore::VerificationResult LocalStore::verifyAllValidPaths(RepairFlag repair
|
|||
database and the filesystem) in the loop below, in order to catch
|
||||
invalid states.
|
||||
*/
|
||||
for (auto & i : DirectoryIterator{realStoreDir.to_string()}) {
|
||||
for (auto & i : DirectoryIterator{config->realStoreDir.get()}) {
|
||||
checkInterrupt();
|
||||
try {
|
||||
storePathsInStoreDir.insert({i.path().filename().string()});
|
||||
|
@ -1664,7 +1658,7 @@ void LocalStore::addBuildLog(const StorePath & drvPath, std::string_view log)
|
|||
|
||||
auto baseName = drvPath.to_string();
|
||||
|
||||
auto logPath = fmt("%s/%s/%s/%s.bz2", logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2));
|
||||
auto logPath = fmt("%s/%s/%s/%s.bz2", config->logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2));
|
||||
|
||||
if (pathExists(logPath)) return;
|
||||
|
||||
|
@ -1682,6 +1676,6 @@ std::optional<std::string> LocalStore::getVersion()
|
|||
return nixVersion;
|
||||
}
|
||||
|
||||
static RegisterStoreImplementation<LocalStore, LocalStoreConfig> regLocalStore;
|
||||
static RegisterStoreImplementation<LocalStore::Config> regLocalStore;
|
||||
|
||||
} // namespace nix
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue