PSA/ee/appliance/host-service/tests/bootstrap-control-plane-script.test.mjs
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

70 lines
3.4 KiB
JavaScript

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
const repoRoot = path.resolve(path.join(import.meta.dirname, '..', '..', '..', '..'));
const bootstrapScript = path.join(repoRoot, 'ee', 'appliance', 'scripts', 'bootstrap-control-plane.sh');
test('T001 host bootstrap dry-run plans minimal k3s, image import, storage/control-plane apply, and setup handoff in order', () => {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'alga-bootstrap-plan-'));
const applianceRoot = path.join(tmp, 'opt', 'alga-appliance');
const imageDir = path.join(applianceRoot, 'control-plane', 'images');
const manifestDir = path.join(applianceRoot, 'control-plane', 'manifests');
const storageDir = path.join(applianceRoot, 'manifests');
const scriptsDir = path.join(applianceRoot, 'scripts');
const tokenFile = path.join(tmp, 'setup-token');
fs.mkdirSync(imageDir, { recursive: true });
fs.mkdirSync(manifestDir, { recursive: true });
fs.mkdirSync(storageDir, { recursive: true });
fs.mkdirSync(scriptsDir, { recursive: true });
fs.writeFileSync(path.join(imageDir, 'control-plane.tar'), 'fake archive');
fs.writeFileSync(path.join(manifestDir, 'kustomization.yaml'), 'resources: []\n');
fs.writeFileSync(path.join(manifestDir, 'namespace.yaml'), 'kind: Namespace\n');
fs.writeFileSync(path.join(storageDir, 'local-path-storage.yaml'), 'kind: List\n');
fs.writeFileSync(path.join(scriptsDir, 'install-storage.sh'), '#!/usr/bin/env bash\n', { mode: 0o755 });
fs.writeFileSync(tokenFile, 'token-123\n');
const result = spawnSync(bootstrapScript, [
'--appliance-root', applianceRoot,
'--kubeconfig', path.join(tmp, 'k3s.yaml'),
'--token-file', tokenFile,
'--port', '18080',
'--dry-run'
], { cwd: repoRoot, encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr || result.stdout);
const output = result.stdout;
const expectedInOrder = [
'Substrate: ensuring k3s is installed and running',
'ensure k3s service is enabled and running with minimal local substrate options',
'Substrate: waiting for Kubernetes API',
'wait for kubectl --kubeconfig',
'Control plane: importing baked image archives',
'k3s ctr images import',
'Control plane: applying local-path storage manifest without waiting for image pulls',
`kubectl --kubeconfig ${path.join(tmp, 'k3s.yaml')} apply -f ${path.join(storageDir, 'local-path-storage.yaml')} || true`,
'Control plane: applying Kubernetes-hosted setup/status manifests',
`kubectl --kubeconfig ${path.join(tmp, 'k3s.yaml')} apply -f ${path.join(manifestDir, 'namespace.yaml')}`,
`kubectl --kubeconfig ${path.join(tmp, 'k3s.yaml')} apply -k ${manifestDir}`,
'Handoff: setup UI should be available from the Kubernetes-hosted control plane',
'One-time setup token: token-123',
`Fallback recovery: sudo ${applianceRoot}/bin/alga-control-plane-reapply`
];
let previous = -1;
for (const needle of expectedInOrder) {
const index = output.indexOf(needle);
assert.notEqual(index, -1, `missing output: ${needle}\n${output}`);
assert.ok(index > previous, `out of order output: ${needle}\n${output}`);
previous = index;
}
assert.match(output, /Alga Appliance bootstrap layers:/);
assert.match(output, /setup handoff: http:\/\/.+:18080\//);
assert.doesNotMatch(output, /\?token=/);
});