mirror of
https://github.com/NixOS/nix
synced 2024-10-18 00:16:11 -04:00
Compare commits
7 commits
a8c2b4c42a
...
f8a0cc1b40
Author | SHA1 | Date | |
---|---|---|---|
f8a0cc1b40 | |||
ab0f9f9089 | |||
de0a34a362 | |||
3c59df412a | |||
bd1961b7cc | |||
30655dd146 | |||
79b1708451 |
|
@ -208,7 +208,7 @@ static git_packbuilder_progress PACKBUILDER_PROGRESS_CHECK_INTERRUPT = &packBuil
|
|||
static void initRepoAtomically(std::filesystem::path &path, bool bare) {
|
||||
if (pathExists(path.string())) return;
|
||||
|
||||
Path tmpDir = createTempDir(std::filesystem::path(path).parent_path());
|
||||
Path tmpDir = createTempDir(os_string_to_string(PathViewNG { std::filesystem::path(path).parent_path() }));
|
||||
AutoDelete delTmpDir(tmpDir, true);
|
||||
Repository tmpRepo;
|
||||
|
||||
|
|
|
@ -95,51 +95,6 @@ struct LocalStore::State::Stmts {
|
|||
SQLiteStmt AddRealisationReference;
|
||||
};
|
||||
|
||||
static int getSchema(Path schemaPath)
|
||||
{
|
||||
int curSchema = 0;
|
||||
if (pathExists(schemaPath)) {
|
||||
auto s = readFile(schemaPath);
|
||||
auto n = string2Int<int>(s);
|
||||
if (!n)
|
||||
throw Error("'%1%' is corrupt", schemaPath);
|
||||
curSchema = *n;
|
||||
}
|
||||
return curSchema;
|
||||
}
|
||||
|
||||
void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd)
|
||||
{
|
||||
const int nixCASchemaVersion = 4;
|
||||
int curCASchema = getSchema(schemaPath);
|
||||
if (curCASchema != nixCASchemaVersion) {
|
||||
if (curCASchema > nixCASchemaVersion) {
|
||||
throw Error("current Nix store ca-schema is version %1%, but I only support %2%",
|
||||
curCASchema, nixCASchemaVersion);
|
||||
}
|
||||
|
||||
if (!lockFile(lockFd.get(), ltWrite, false)) {
|
||||
printInfo("waiting for exclusive access to the Nix store for ca drvs...");
|
||||
lockFile(lockFd.get(), ltNone, false); // We have acquired a shared lock; release it to prevent deadlocks
|
||||
lockFile(lockFd.get(), ltWrite, true);
|
||||
}
|
||||
|
||||
if (curCASchema == 0) {
|
||||
static const char schema[] =
|
||||
#include "ca-specific-schema.sql.gen.hh"
|
||||
;
|
||||
db.exec(schema);
|
||||
curCASchema = nixCASchemaVersion;
|
||||
}
|
||||
|
||||
if (curCASchema < 4)
|
||||
throw Error("experimental CA schema version %d is no longer supported", curCASchema);
|
||||
|
||||
writeFile(schemaPath, fmt("%d", nixCASchemaVersion), 0666, true);
|
||||
lockFile(lockFd.get(), ltRead, true);
|
||||
}
|
||||
}
|
||||
|
||||
LocalStore::LocalStore(
|
||||
std::string_view scheme,
|
||||
PathView path,
|
||||
|
@ -316,6 +271,10 @@ LocalStore::LocalStore(
|
|||
|
||||
openDB(*state, false);
|
||||
|
||||
/* Legacy database schema migrations. Don't bump 'schema' for
|
||||
new migrations; instead, add a migration to
|
||||
upgradeDBSchema(). */
|
||||
|
||||
if (curSchema < 8) {
|
||||
SQLiteTxn txn(state->db);
|
||||
state->db.exec("alter table ValidPaths add column ultimate integer");
|
||||
|
@ -342,13 +301,7 @@ LocalStore::LocalStore(
|
|||
|
||||
else openDB(*state, false);
|
||||
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||
if (!readOnly) {
|
||||
migrateCASchema(state->db, dbDir + "/ca-schema", globalLock);
|
||||
} else {
|
||||
throw Error("need to migrate to content-addressed schema, but this cannot be done in read-only mode");
|
||||
}
|
||||
}
|
||||
upgradeDBSchema(*state);
|
||||
|
||||
/* Prepare SQL statements. */
|
||||
state->stmts->RegisterValidPath.create(state->db,
|
||||
|
@ -483,7 +436,17 @@ std::string LocalStore::getUri()
|
|||
|
||||
|
||||
int LocalStore::getSchema()
|
||||
{ return nix::getSchema(schemaPath); }
|
||||
{
|
||||
int curSchema = 0;
|
||||
if (pathExists(schemaPath)) {
|
||||
auto s = readFile(schemaPath);
|
||||
auto n = string2Int<int>(s);
|
||||
if (!n)
|
||||
throw Error("'%1%' is corrupt", schemaPath);
|
||||
curSchema = *n;
|
||||
}
|
||||
return curSchema;
|
||||
}
|
||||
|
||||
void LocalStore::openDB(State & state, bool create)
|
||||
{
|
||||
|
@ -566,6 +529,42 @@ void LocalStore::openDB(State & state, bool create)
|
|||
}
|
||||
|
||||
|
||||
void LocalStore::upgradeDBSchema(State & state)
|
||||
{
|
||||
state.db.exec("create table if not exists SchemaMigrations (migration text primary key not null);");
|
||||
|
||||
std::set<std::string> schemaMigrations;
|
||||
|
||||
{
|
||||
SQLiteStmt querySchemaMigrations;
|
||||
querySchemaMigrations.create(state.db, "select migration from SchemaMigrations;");
|
||||
auto useQuerySchemaMigrations(querySchemaMigrations.use());
|
||||
while (useQuerySchemaMigrations.next())
|
||||
schemaMigrations.insert(useQuerySchemaMigrations.getStr(0));
|
||||
}
|
||||
|
||||
auto doUpgrade = [&](const std::string & migrationName, const std::string & stmt)
|
||||
{
|
||||
if (schemaMigrations.contains(migrationName))
|
||||
return;
|
||||
|
||||
warn("executing Nix database schema migration '%s'...", migrationName);
|
||||
|
||||
SQLiteTxn txn(state.db);
|
||||
state.db.exec(stmt + fmt("\ninsert into SchemaMigrations values('%s')", migrationName));
|
||||
txn.commit();
|
||||
|
||||
schemaMigrations.insert(migrationName);
|
||||
};
|
||||
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations))
|
||||
doUpgrade(
|
||||
"20220326-ca-derivations",
|
||||
#include "ca-specific-schema.sql.gen.hh"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* To improve purity, users may want to make the Nix store a read-only
|
||||
bind mount. So make the Nix store writable for this process. */
|
||||
void LocalStore::makeStoreWritable()
|
||||
|
|
|
@ -356,6 +356,8 @@ private:
|
|||
|
||||
void openDB(State & state, bool create);
|
||||
|
||||
void upgradeDBSchema(State & state);
|
||||
|
||||
void makeStoreWritable();
|
||||
|
||||
uint64_t queryValidPathId(State & state, const StorePath & path);
|
||||
|
|
|
@ -50,8 +50,9 @@ R""(
|
|||
|
||||
# Description
|
||||
|
||||
This command evaluates the given Nix expression and prints the
|
||||
result on standard output.
|
||||
This command evaluates the given Nix expression, and prints the result on standard output.
|
||||
|
||||
It also evaluates any nested attribute values and list items.
|
||||
|
||||
# Output format
|
||||
|
||||
|
|
|
@ -212,18 +212,23 @@ nix_symlinks = [
|
|||
'nix-store',
|
||||
]
|
||||
|
||||
executable_suffix = ''
|
||||
if host_machine.system() == 'windows'
|
||||
executable_suffix = '.exe'
|
||||
endif
|
||||
|
||||
foreach linkname : nix_symlinks
|
||||
install_symlink(
|
||||
linkname,
|
||||
linkname + executable_suffix,
|
||||
# TODO(Qyriad): should these continue to be relative symlinks?
|
||||
pointing_to : 'nix',
|
||||
pointing_to : fs.name(this_exe),
|
||||
install_dir : get_option('bindir'),
|
||||
# The 'runtime' tag is what executables default to, which we want to emulate here.
|
||||
install_tag : 'runtime'
|
||||
)
|
||||
t = custom_target(
|
||||
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
||||
output: linkname,
|
||||
output: linkname + executable_suffix,
|
||||
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
||||
build_by_default: true
|
||||
)
|
||||
|
@ -233,15 +238,15 @@ endforeach
|
|||
|
||||
install_symlink(
|
||||
'build-remote',
|
||||
pointing_to : '..' / '..'/ get_option('bindir') / 'nix',
|
||||
install_dir : get_option('libexecdir') / 'nix',
|
||||
pointing_to : '..' / '..'/ get_option('bindir') / fs.name(this_exe),
|
||||
install_dir : get_option('libexecdir') / fs.name(this_exe),
|
||||
# The 'runtime' tag is what executables default to, which we want to emulate here.
|
||||
install_tag : 'runtime'
|
||||
)
|
||||
|
||||
custom_target(
|
||||
command: ['ln', '-sf', fs.name(this_exe), '@OUTPUT@'],
|
||||
output: 'build-remote',
|
||||
output: 'build-remote' + executable_suffix,
|
||||
# TODO(Ericson2314): Don't do this once we have the `meson.override_find_program` working)
|
||||
build_by_default: true
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue