mirror of
https://github.com/morluto/rea.git
synced 2026-11-10 16:57:19 +00:00
fix(setup): preserve registration identity and recovery ownership
Keep layered environment choices, current byte-exact recovery snapshots, and package-manager failure details. Report pinned package drift without claiming runner resolution. Retain failed Linux installer cleanup for host-owned retry while preserving the install outcome. Reviewed fixes include #2632, #2769, #2783, #2959, #2979, #2983, #2995, #3009, and #2559. Validation: 98 focused setup/registration tests passed; 45 Linux installer tests passed. Real Linux package installation remains unverified.
This commit is contained in:
1 parent
599a8ee11d
commit
ec56c1da04
42 files changed
+2418
-213
No files matched your search
@@ -11,6 +11,21 @@ import {
|
||||
import type { SetupClient } from "./SupportedClients.js";
|
||||
import { clientRegistrationEnvironment } from "./ClientRegistrationEnvironment.js";
|
||||
import type { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
|
||||
import type { ConfigurationError } from "../domain/configurationErrors.js";
|
||||
|
||||
/** A parsed layer retains its path so rereading the write target replaces only that layer. */
|
||||
export interface ClientConfigurationSource extends ClientConfigurationDocument {
|
||||
readonly sourcePath: string;
|
||||
}
|
||||
|
||||
const invalidEnvironment = (
|
||||
path: string,
|
||||
error: ConfigurationError,
|
||||
): ClientConfigurationFileError => ({
|
||||
kind: "malformed",
|
||||
path,
|
||||
detail: `Configuration ${path} has an invalid REA server environment: ${error.settings.map(({ setting, constraint }) => `${setting}: ${constraint}`).join("; ")}. Repair it before rerunning setup.`,
|
||||
});
|
||||
|
||||
/** A named source failure that setup can explain without losing the bad path. */
|
||||
export interface ClientConfigurationFileError {
|
||||
@@ -74,9 +89,9 @@ export const readClientConfigurationFiles = async (
|
||||
client: SetupClient,
|
||||
resources?: ArtifactResourceScope,
|
||||
): Promise<
|
||||
Result<readonly ClientConfigurationDocument[], ClientConfigurationFileError>
|
||||
Result<readonly ClientConfigurationSource[], ClientConfigurationFileError>
|
||||
> => {
|
||||
const documents: ClientConfigurationDocument[] = [];
|
||||
const documents: ClientConfigurationSource[] = [];
|
||||
for (const path of client.configPaths ?? [client.configPath]) {
|
||||
const document = await readConfigurationFile(
|
||||
path,
|
||||
@@ -85,16 +100,21 @@ export const readClientConfigurationFiles = async (
|
||||
);
|
||||
if (!document.ok) return document;
|
||||
if (document.value !== undefined) {
|
||||
const environment = clientRegistrationEnvironment(document.value);
|
||||
const environment = clientRegistrationEnvironment(
|
||||
document.value,
|
||||
{},
|
||||
"fragment",
|
||||
);
|
||||
if (!environment.ok)
|
||||
return err({
|
||||
kind: "malformed",
|
||||
path,
|
||||
detail: `Configuration ${path} has an invalid REA server environment: ${environment.error.settings.map(({ setting, constraint }) => `${setting}: ${constraint}`).join("; ")}. Repair it before rerunning setup.`,
|
||||
});
|
||||
documents.push(document.value);
|
||||
return err(invalidEnvironment(path, environment.error));
|
||||
documents.push({ ...document.value, sourcePath: path });
|
||||
}
|
||||
}
|
||||
const environment = clientRegistrationEnvironment(
|
||||
effectiveClientConfiguration(documents),
|
||||
);
|
||||
if (!environment.ok)
|
||||
return err(invalidEnvironment(client.configPath, environment.error));
|
||||
return ok(documents);
|
||||
};
|
||||
|
||||
@@ -117,8 +137,24 @@ const isObject = (value: unknown): value is Record<string, unknown> =>
|
||||
|
||||
/** Project a client's effective user registration without modifying its source files. */
|
||||
export const effectiveClientConfiguration = (
|
||||
documents: readonly ClientConfigurationDocument[],
|
||||
sources: readonly ClientConfigurationSource[],
|
||||
target?: {
|
||||
readonly client: Pick<SetupClient, "configPath" | "configPaths">;
|
||||
readonly document: ClientConfigurationDocument | undefined;
|
||||
},
|
||||
): ClientConfigurationDocument | undefined => {
|
||||
const documents =
|
||||
target === undefined
|
||||
? sources
|
||||
: (target.client.configPaths ?? [target.client.configPath]).flatMap(
|
||||
(path) => {
|
||||
const document =
|
||||
path === target.client.configPath
|
||||
? target.document
|
||||
: sources.find(({ sourcePath }) => sourcePath === path);
|
||||
return document === undefined ? [] : [document];
|
||||
},
|
||||
);
|
||||
const last = documents.at(-1);
|
||||
if (last === undefined) return undefined;
|
||||
if (documents.length === 1) return last;
|
||||
|
||||
Reference in new issue
Block a user