Drop unreleased scheduler migration
Debian Trixie package bundle / packages (push) Successful in 22m18s
Debian Trixie package bundle / packages (push) Successful in 22m18s
This commit is contained in:
+3
-4
@@ -51,9 +51,8 @@ must be moved behind `bongostore` and its NMAP interface:
|
||||
|
||||
TLSRPT and the worker scheduler originally joined that list during
|
||||
development, but have already moved into the `_system` Store and no longer
|
||||
own separate databases. An existing `/var/lib/bongo/worker/jobs.sqlite` is
|
||||
imported once and renamed to
|
||||
`jobs.sqlite.migrated-to-system-store`.
|
||||
own separate databases. Because these paths existed only in unreleased 0.7
|
||||
development builds, no production migration is required.
|
||||
|
||||
Sieve scripts and vacation state belong to the Store of the user who owns
|
||||
them. External account definitions, encrypted credentials, destination
|
||||
@@ -62,7 +61,7 @@ duplicate-detection state likewise belong to that user's Store. The `_system`
|
||||
Store holds only a credential-free due index containing the owner, account ID,
|
||||
and next collection time, so `bongocollector` need not scan every account.
|
||||
The two remaining standalone paths are transitional until their Store
|
||||
protocol migrations and one-time data imports have landed.
|
||||
protocol migrations have landed.
|
||||
|
||||
Web tasks, sender identities, and signatures are ordinary user Store
|
||||
documents below `/preferences`. Login sessions exist only in `bongoweb`
|
||||
|
||||
@@ -74,9 +74,6 @@ int BongoSchedulerOpen(BongoScheduler **scheduler, const char *database_path);
|
||||
int BongoSchedulerAttach(BongoScheduler **scheduler, sqlite3 *database);
|
||||
int BongoSchedulerBorrow(BongoScheduler **scheduler, sqlite3 *database);
|
||||
int BongoSchedulerOpenNmap(BongoScheduler **scheduler);
|
||||
int BongoSchedulerMigrateLegacy(BongoScheduler *scheduler,
|
||||
const char *legacy_path,
|
||||
const char *archive_path);
|
||||
void BongoSchedulerClose(BongoScheduler **scheduler);
|
||||
|
||||
/* Synchronize the compiled/configured registry while preserving run history. */
|
||||
|
||||
@@ -116,17 +116,9 @@ StoreDBOpen(StoreClient *client, const char *user)
|
||||
if (!strcmp(user, "_system")) {
|
||||
BongoScheduler *scheduler = NULL;
|
||||
BongoTlsRptStore *tlsrpt = NULL;
|
||||
char scheduler_archive[XPL_MAX_PATH + 1];
|
||||
|
||||
if (!BongoTlsRptStoreAttach(&tlsrpt, entry->handle->db) ||
|
||||
!BongoSchedulerAttach(&scheduler, entry->handle->db) ||
|
||||
snprintf(scheduler_archive, sizeof(scheduler_archive),
|
||||
"%s.migrated-to-system-store",
|
||||
XPL_DEFAULT_WORKER_DB) >=
|
||||
(int)sizeof(scheduler_archive) ||
|
||||
!BongoSchedulerMigrateLegacy(
|
||||
scheduler, XPL_DEFAULT_WORKER_DB,
|
||||
scheduler_archive)) {
|
||||
!BongoSchedulerAttach(&scheduler, entry->handle->db)) {
|
||||
BongoSchedulerClose(&scheduler);
|
||||
BongoTlsRptStoreClose(&tlsrpt);
|
||||
MsgSQLClose(entry->handle);
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "scheduler-private.h"
|
||||
|
||||
@@ -243,129 +241,6 @@ BongoSchedulerAttach(BongoScheduler **output, sqlite3 *database)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
AttachedTableExists(sqlite3 *database, const char *schema, const char *table)
|
||||
{
|
||||
sqlite3_stmt *statement = NULL;
|
||||
char query[256];
|
||||
int exists = 0;
|
||||
|
||||
if (snprintf(query, sizeof(query),
|
||||
"SELECT 1 FROM %s.sqlite_master "
|
||||
"WHERE type='table' AND name=?",
|
||||
schema) >= (int)sizeof(query) ||
|
||||
sqlite3_prepare_v2(database, query, -1, &statement, NULL) !=
|
||||
SQLITE_OK ||
|
||||
sqlite3_bind_text(statement, 1, table, -1, SQLITE_STATIC) !=
|
||||
SQLITE_OK)
|
||||
goto done;
|
||||
exists = sqlite3_step(statement) == SQLITE_ROW;
|
||||
done:
|
||||
sqlite3_finalize(statement);
|
||||
return exists;
|
||||
}
|
||||
|
||||
static int
|
||||
AttachedColumnExists(sqlite3 *database, const char *schema,
|
||||
const char *table, const char *column)
|
||||
{
|
||||
sqlite3_stmt *statement = NULL;
|
||||
char query[256];
|
||||
int step;
|
||||
int exists = 0;
|
||||
|
||||
if (snprintf(query, sizeof(query), "PRAGMA %s.table_info(%s)",
|
||||
schema, table) >= (int)sizeof(query) ||
|
||||
sqlite3_prepare_v2(database, query, -1, &statement, NULL) !=
|
||||
SQLITE_OK)
|
||||
goto done;
|
||||
while ((step = sqlite3_step(statement)) == SQLITE_ROW) {
|
||||
const unsigned char *name = sqlite3_column_text(statement, 1);
|
||||
if (name && strcmp((const char *)name, column) == 0) {
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
sqlite3_finalize(statement);
|
||||
return exists;
|
||||
}
|
||||
|
||||
int
|
||||
BongoSchedulerMigrateLegacy(BongoScheduler *scheduler,
|
||||
const char *legacy_path,
|
||||
const char *archive_path)
|
||||
{
|
||||
static const char Columns[] =
|
||||
"name,enabled,interval_seconds,jitter_seconds,retry_initial_seconds,"
|
||||
"retry_max_seconds,next_run,not_before,last_started,last_finished,"
|
||||
"last_success,consecutive_failures,running,requested,run_token,"
|
||||
"last_error";
|
||||
sqlite3_stmt *attach = NULL;
|
||||
char import[2048];
|
||||
int has_not_before;
|
||||
int attached = 0;
|
||||
int transaction = 0;
|
||||
int result = 0;
|
||||
|
||||
if (!scheduler || !scheduler->database || scheduler->connection ||
|
||||
!legacy_path || !*legacy_path || !archive_path || !*archive_path)
|
||||
return 0;
|
||||
if (access(legacy_path, F_OK) != 0)
|
||||
return errno == ENOENT;
|
||||
if (access(archive_path, F_OK) == 0)
|
||||
return 0;
|
||||
if (sqlite3_prepare_v2(scheduler->database,
|
||||
"ATTACH DATABASE ? AS legacy_scheduler", -1,
|
||||
&attach, NULL) != SQLITE_OK ||
|
||||
sqlite3_bind_text(attach, 1, legacy_path, -1, SQLITE_TRANSIENT) !=
|
||||
SQLITE_OK ||
|
||||
sqlite3_step(attach) != SQLITE_DONE)
|
||||
goto done;
|
||||
sqlite3_finalize(attach);
|
||||
attach = NULL;
|
||||
attached = 1;
|
||||
if (!AttachedTableExists(
|
||||
scheduler->database, "legacy_scheduler", "scheduler_jobs"))
|
||||
goto done;
|
||||
has_not_before = AttachedColumnExists(
|
||||
scheduler->database, "legacy_scheduler", "scheduler_jobs",
|
||||
"not_before");
|
||||
if (snprintf(import, sizeof(import),
|
||||
"INSERT OR IGNORE INTO main.scheduler_jobs(%s) "
|
||||
"SELECT name,enabled,interval_seconds,jitter_seconds,"
|
||||
"retry_initial_seconds,retry_max_seconds,next_run,%s,"
|
||||
"last_started,last_finished,last_success,"
|
||||
"consecutive_failures,running,requested,run_token,last_error "
|
||||
"FROM legacy_scheduler.scheduler_jobs",
|
||||
Columns, has_not_before ? "not_before" : "0") >=
|
||||
(int)sizeof(import))
|
||||
goto done;
|
||||
if (!Begin(scheduler->database)) goto done;
|
||||
transaction = 1;
|
||||
if (sqlite3_exec(scheduler->database, import, NULL, NULL, NULL) !=
|
||||
SQLITE_OK ||
|
||||
!Commit(scheduler->database))
|
||||
goto done;
|
||||
transaction = 0;
|
||||
if (sqlite3_exec(scheduler->database,
|
||||
"DETACH DATABASE legacy_scheduler",
|
||||
NULL, NULL, NULL) != SQLITE_OK)
|
||||
goto done;
|
||||
attached = 0;
|
||||
if (rename(legacy_path, archive_path) != 0)
|
||||
goto done;
|
||||
result = 1;
|
||||
done:
|
||||
sqlite3_finalize(attach);
|
||||
if (transaction) Rollback(scheduler->database);
|
||||
if (attached)
|
||||
(void)sqlite3_exec(scheduler->database,
|
||||
"DETACH DATABASE legacy_scheduler",
|
||||
NULL, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
BongoSchedulerClose(BongoScheduler **scheduler)
|
||||
{
|
||||
|
||||
@@ -54,13 +54,8 @@ main(void)
|
||||
{"dmarc-report", 0, 86400, 0, 300, 21600}
|
||||
};
|
||||
char database[] = "/tmp/bongo-scheduler-test-XXXXXX";
|
||||
char migrated_database[] = "/tmp/bongo-scheduler-migrated-test-XXXXXX";
|
||||
char legacy_database[] = "/tmp/bongo-scheduler-legacy-test-XXXXXX";
|
||||
char legacy_archive[sizeof(legacy_database) + 16];
|
||||
char sidecar[sizeof(database) + 8];
|
||||
int descriptor;
|
||||
int migrated_descriptor;
|
||||
int legacy_descriptor;
|
||||
int count = 0;
|
||||
int failed = 0;
|
||||
|
||||
@@ -156,46 +151,10 @@ main(void)
|
||||
|
||||
BongoSchedulerClose(&scheduler);
|
||||
|
||||
migrated_descriptor = mkstemp(migrated_database);
|
||||
legacy_descriptor = mkstemp(legacy_database);
|
||||
failed |= Check(migrated_descriptor >= 0 && legacy_descriptor >= 0,
|
||||
"cannot create scheduler migration databases");
|
||||
if (migrated_descriptor >= 0) close(migrated_descriptor);
|
||||
if (legacy_descriptor >= 0) close(legacy_descriptor);
|
||||
snprintf(legacy_archive, sizeof(legacy_archive), "%s.migrated",
|
||||
legacy_database);
|
||||
failed |= Check(!failed &&
|
||||
BongoSchedulerOpen(&scheduler, legacy_database) &&
|
||||
BongoSchedulerSync(scheduler, jobs, 2, 900) &&
|
||||
BongoSchedulerClaimDue(scheduler, 900, &lease) == 1 &&
|
||||
BongoSchedulerFinish(
|
||||
scheduler, &lease, 0, "legacy failure", 901) == 1,
|
||||
"cannot prepare legacy scheduler state");
|
||||
BongoSchedulerClose(&scheduler);
|
||||
failed |= Check(!failed &&
|
||||
BongoSchedulerOpen(&scheduler, migrated_database) &&
|
||||
BongoSchedulerMigrateLegacy(
|
||||
scheduler, legacy_database, legacy_archive),
|
||||
"cannot migrate legacy scheduler state");
|
||||
failed |= Check(!failed && access(legacy_database, F_OK) != 0 &&
|
||||
access(legacy_archive, F_OK) == 0,
|
||||
"legacy scheduler database was not archived");
|
||||
failed |= Check(!failed &&
|
||||
BongoSchedulerGetStatus(
|
||||
scheduler, "acme-renew", &status) == 1 &&
|
||||
status.consecutive_failures == 1 &&
|
||||
status.next_run == 911 &&
|
||||
strcmp(status.last_error, "legacy failure") == 0,
|
||||
"legacy scheduler state was not preserved");
|
||||
BongoSchedulerClose(&scheduler);
|
||||
|
||||
unlink(database);
|
||||
snprintf(sidecar, sizeof(sidecar), "%s-wal", database);
|
||||
unlink(sidecar);
|
||||
snprintf(sidecar, sizeof(sidecar), "%s-shm", database);
|
||||
unlink(sidecar);
|
||||
unlink(migrated_database);
|
||||
unlink(legacy_database);
|
||||
unlink(legacy_archive);
|
||||
return failed ? 1 : 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user