mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 20:50:22 +00:00
Matrix: harden legacy migration fallback
This commit is contained in:
@@ -150,6 +150,32 @@ describe("matrix client storage paths", () => {
|
||||
expect(fs.existsSync(storagePaths.cryptoPath)).toBe(true);
|
||||
});
|
||||
|
||||
it("continues migrating whichever legacy artifact is still missing", async () => {
|
||||
const stateDir = setupStateDir();
|
||||
const storagePaths = resolveMatrixStoragePaths({
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "secret-token",
|
||||
env: {},
|
||||
});
|
||||
const legacyRoot = path.join(stateDir, "matrix");
|
||||
fs.mkdirSync(storagePaths.rootDir, { recursive: true });
|
||||
fs.writeFileSync(storagePaths.storagePath, '{"new":true}');
|
||||
fs.mkdirSync(path.join(legacyRoot, "crypto"), { recursive: true });
|
||||
|
||||
await maybeMigrateLegacyStorage({
|
||||
storagePaths,
|
||||
env: {},
|
||||
});
|
||||
|
||||
expect(maybeCreateMatrixMigrationSnapshotMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ trigger: "matrix-client-fallback" }),
|
||||
);
|
||||
expect(fs.readFileSync(storagePaths.storagePath, "utf8")).toBe('{"new":true}');
|
||||
expect(fs.existsSync(path.join(legacyRoot, "crypto"))).toBe(false);
|
||||
expect(fs.existsSync(storagePaths.cryptoPath)).toBe(true);
|
||||
});
|
||||
|
||||
it("refuses to migrate legacy storage when the snapshot step fails", async () => {
|
||||
const stateDir = setupStateDir();
|
||||
const storagePaths = resolveMatrixStoragePaths({
|
||||
|
||||
@@ -185,18 +185,20 @@ export async function maybeMigrateLegacyStorage(params: {
|
||||
storagePaths: MatrixStoragePaths;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<void> {
|
||||
const hasNewStorage =
|
||||
fs.existsSync(params.storagePaths.storagePath) || fs.existsSync(params.storagePaths.cryptoPath);
|
||||
if (hasNewStorage) {
|
||||
return;
|
||||
}
|
||||
|
||||
const legacy = resolveLegacyStoragePaths(params.env);
|
||||
const hasLegacyStorage = fs.existsSync(legacy.storagePath);
|
||||
const hasLegacyCrypto = fs.existsSync(legacy.cryptoPath);
|
||||
if (!hasLegacyStorage && !hasLegacyCrypto) {
|
||||
return;
|
||||
}
|
||||
const hasTargetStorage = fs.existsSync(params.storagePaths.storagePath);
|
||||
const hasTargetCrypto = fs.existsSync(params.storagePaths.cryptoPath);
|
||||
// Continue partial migrations one artifact at a time; only skip items whose targets already exist.
|
||||
const shouldMigrateStorage = hasLegacyStorage && !hasTargetStorage;
|
||||
const shouldMigrateCrypto = hasLegacyCrypto && !hasTargetCrypto;
|
||||
if (!shouldMigrateStorage && !shouldMigrateCrypto) {
|
||||
return;
|
||||
}
|
||||
|
||||
assertLegacyMigrationAccountSelection({
|
||||
accountKey: params.storagePaths.accountKey,
|
||||
@@ -210,22 +212,31 @@ export async function maybeMigrateLegacyStorage(params: {
|
||||
});
|
||||
fs.mkdirSync(params.storagePaths.rootDir, { recursive: true });
|
||||
const moved: LegacyMoveRecord[] = [];
|
||||
const skippedExistingTargets: string[] = [];
|
||||
try {
|
||||
if (hasLegacyStorage) {
|
||||
if (shouldMigrateStorage) {
|
||||
moveLegacyStoragePathOrThrow({
|
||||
sourcePath: legacy.storagePath,
|
||||
targetPath: params.storagePaths.storagePath,
|
||||
label: "sync store",
|
||||
moved,
|
||||
});
|
||||
} else if (hasLegacyStorage) {
|
||||
skippedExistingTargets.push(
|
||||
`- sync store remains at ${legacy.storagePath} because ${params.storagePaths.storagePath} already exists`,
|
||||
);
|
||||
}
|
||||
if (hasLegacyCrypto) {
|
||||
if (shouldMigrateCrypto) {
|
||||
moveLegacyStoragePathOrThrow({
|
||||
sourcePath: legacy.cryptoPath,
|
||||
targetPath: params.storagePaths.cryptoPath,
|
||||
label: "crypto store",
|
||||
moved,
|
||||
});
|
||||
} else if (hasLegacyCrypto) {
|
||||
skippedExistingTargets.push(
|
||||
`- crypto store remains at ${legacy.cryptoPath} because ${params.storagePaths.cryptoPath} already exists`,
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
const rollbackError = rollbackLegacyMoves(moved);
|
||||
@@ -242,6 +253,11 @@ export async function maybeMigrateLegacyStorage(params: {
|
||||
.join("\n")}`,
|
||||
);
|
||||
}
|
||||
if (skippedExistingTargets.length > 0) {
|
||||
logger.warn?.(
|
||||
`matrix: legacy client storage still exists in the flat path because some account-scoped targets already existed.\n${skippedExistingTargets.join("\n")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function moveLegacyStoragePathOrThrow(params: {
|
||||
|
||||
Reference in New Issue
Block a user