mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-20 07:13:05 +00:00
feat(onboarding): add first-run environment checker (#1290)
* feat(onboarding): add first-run environment checker Add a preflight that checks whether the host can run Docker deploys before a deploy fails for an avoidable reason. It verifies the Docker engine is reachable and permitted, the Compose plugin is present, the compose directory is writable and mounted at a matching host path, the dashboard is behind TLS, and the compose volume has disk headroom. Each result that needs attention carries a specific fix rather than a generic error, and the checks never block: an operator who knows their setup can continue. The checks run as the final step of first-boot setup and can be re-run any time from the Recovery settings tab. A new admin-only endpoint, GET /api/diagnostics/environment, backs both surfaces. * fix(onboarding): distinguish unverified path mapping and support parent binds Treat a container whose self-inspect fails as an unverified path-mapping warning instead of a false "not containerized" pass, so an unverifiable mapping never reads as healthy. Resolve the compose directory through the longest-prefix bind mount and compare the host path it resolves to, so a parent bind such as -v /opt:/opt correctly covers COMPOSE_DIR=/opt/compose instead of warning that the directory is not bind-mounted. * test(e2e): advance the setup wizard past the environment step in loginAs The first-run setup helper clicked "Initialize console" and immediately waited for the dashboard, but setup now shows an environment-preflight step before landing the console. Click "Enter Sencho" to complete onboarding before asserting the dashboard, so the first test on a fresh instance passes.
This commit is contained in:
@@ -154,6 +154,32 @@ class SelfIdentityService {
|
||||
return this.volumeNames.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind mounts on the running Sencho container, used by the environment
|
||||
* checker to verify the compose directory is mounted at the same path on the
|
||||
* host and inside the container. Returns null when Sencho is not running in
|
||||
* Docker (dev / bare metal), where the 1:1 path-mapping concern does not
|
||||
* apply. Throws when Sencho IS containerized (a container id was resolved at
|
||||
* startup) but its own mounts cannot be read now, so the caller can report an
|
||||
* unverified state instead of a false "not containerized". Re-inspects on
|
||||
* each call rather than caching, because it runs only on an admin-triggered
|
||||
* diagnostic.
|
||||
*/
|
||||
async getBindMounts(): Promise<Array<{ source: string; destination: string }> | null> {
|
||||
const docker = DockerController.getInstance().getDocker();
|
||||
const info = await this.resolveSelfInspect(docker);
|
||||
if (!info) {
|
||||
if (this.containerId) {
|
||||
throw new Error('container self-inspect unavailable; cannot read mounts');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const mounts = (info.Mounts ?? []) as Array<{ Type?: string; Source?: string; Destination?: string }>;
|
||||
return mounts
|
||||
.filter(m => m.Type === 'bind' && m.Source && m.Destination)
|
||||
.map(m => ({ source: m.Source as string, destination: m.Destination as string }));
|
||||
}
|
||||
|
||||
/** Diagnostic snapshot used by route handlers when composing error responses. */
|
||||
getIdentity(): {
|
||||
containerId: string | null;
|
||||
|
||||
Reference in New Issue
Block a user