@envsync-cloud/deploy-cli 0.6.11 → 0.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +33 -52
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ var KEYCLOAK_REALM_FILE = "/opt/envsync/deploy/keycloak-realm.envsync.json";
|
|
|
25
25
|
var NGINX_WEB_CONF = "/opt/envsync/deploy/nginx-web.conf";
|
|
26
26
|
var NGINX_LANDING_CONF = "/opt/envsync/deploy/nginx-landing.conf";
|
|
27
27
|
var OTEL_AGENT_CONF = "/opt/envsync/deploy/otel-agent.yaml";
|
|
28
|
+
var CLICKSTACK_CLICKHOUSE_CONF = "/opt/envsync/deploy/clickhouse-listen.xml";
|
|
28
29
|
var INTERNAL_CONFIG_JSON = "/opt/envsync/deploy/config.json";
|
|
29
30
|
var STACK_VOLUMES = [
|
|
30
31
|
"postgres_data",
|
|
@@ -757,6 +758,14 @@ function renderOtelAgentConfig(config) {
|
|
|
757
758
|
" exporters: [otlphttp/clickstack]"
|
|
758
759
|
].join("\n") + "\n";
|
|
759
760
|
}
|
|
761
|
+
function renderClickstackClickHouseConfig() {
|
|
762
|
+
return [
|
|
763
|
+
"<clickhouse>",
|
|
764
|
+
" <listen_host>0.0.0.0</listen_host>",
|
|
765
|
+
" <listen_try>1</listen_try>",
|
|
766
|
+
"</clickhouse>"
|
|
767
|
+
].join("\n") + "\n";
|
|
768
|
+
}
|
|
760
769
|
function renderStack(config, runtimeEnv, mode) {
|
|
761
770
|
const hosts = domainMap(config.domain.root_domain);
|
|
762
771
|
const includeRuntimeInfra = mode !== "base";
|
|
@@ -956,7 +965,10 @@ ${renderEnvList({
|
|
|
956
965
|
- clickstack_data:/data/db
|
|
957
966
|
- clickstack_ch_data:/var/lib/clickhouse
|
|
958
967
|
- clickstack_ch_logs:/var/log/clickhouse-server
|
|
968
|
+
- ${CLICKSTACK_CLICKHOUSE_CONF}:/etc/clickhouse-server/config.d/envsync-listen-host.xml:ro
|
|
959
969
|
networks: [envsync]
|
|
970
|
+
healthcheck:
|
|
971
|
+
disable: true
|
|
960
972
|
|
|
961
973
|
otel-agent:
|
|
962
974
|
image: ${config.images.otel_agent}
|
|
@@ -1026,6 +1038,7 @@ function writeDeployArtifacts(config, generated) {
|
|
|
1026
1038
|
writeFileMaybe(NGINX_WEB_CONF, renderNginxConf("web"));
|
|
1027
1039
|
writeFileMaybe(NGINX_LANDING_CONF, renderNginxConf("landing"));
|
|
1028
1040
|
writeFileMaybe(OTEL_AGENT_CONF, renderOtelAgentConfig(config));
|
|
1041
|
+
writeFileMaybe(CLICKSTACK_CLICKHOUSE_CONF, renderClickstackClickHouseConfig());
|
|
1029
1042
|
logSuccess(currentOptions.dryRun ? "Deploy artifacts previewed" : "Deploy artifacts written");
|
|
1030
1043
|
}
|
|
1031
1044
|
function saveDesiredConfig(config) {
|
|
@@ -1172,51 +1185,6 @@ function waitForHttpService(config, label, url, timeoutSeconds = 120) {
|
|
|
1172
1185
|
}
|
|
1173
1186
|
throw new Error(`Timed out waiting for ${label} at ${url}`);
|
|
1174
1187
|
}
|
|
1175
|
-
function serviceContainerId(config, serviceName) {
|
|
1176
|
-
const output = tryRun(
|
|
1177
|
-
"docker",
|
|
1178
|
-
[
|
|
1179
|
-
"ps",
|
|
1180
|
-
"--filter",
|
|
1181
|
-
`label=com.docker.swarm.service.name=${config.services.stack_name}_${serviceName}`,
|
|
1182
|
-
"--format",
|
|
1183
|
-
"{{.ID}}"
|
|
1184
|
-
],
|
|
1185
|
-
{ quiet: true }
|
|
1186
|
-
);
|
|
1187
|
-
return output.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? "";
|
|
1188
|
-
}
|
|
1189
|
-
function waitForContainerHealth(config, serviceName, label, timeoutSeconds = 180) {
|
|
1190
|
-
if (currentOptions.dryRun) {
|
|
1191
|
-
logDryRun(`Would wait for ${label}`);
|
|
1192
|
-
return;
|
|
1193
|
-
}
|
|
1194
|
-
logStep(`Waiting for ${label}`);
|
|
1195
|
-
const deadline = Date.now() + timeoutSeconds * 1e3;
|
|
1196
|
-
while (Date.now() < deadline) {
|
|
1197
|
-
const containerId = serviceContainerId(config, serviceName);
|
|
1198
|
-
if (!containerId) {
|
|
1199
|
-
sleepSeconds(2);
|
|
1200
|
-
continue;
|
|
1201
|
-
}
|
|
1202
|
-
const health = tryRun(
|
|
1203
|
-
"docker",
|
|
1204
|
-
[
|
|
1205
|
-
"inspect",
|
|
1206
|
-
"--format",
|
|
1207
|
-
"{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}",
|
|
1208
|
-
containerId
|
|
1209
|
-
],
|
|
1210
|
-
{ quiet: true }
|
|
1211
|
-
).trim();
|
|
1212
|
-
if (health === "healthy" || health === "running") {
|
|
1213
|
-
logSuccess(`${label} is ready`);
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
sleepSeconds(2);
|
|
1217
|
-
}
|
|
1218
|
-
throw new Error(`Timed out waiting for ${label}`);
|
|
1219
|
-
}
|
|
1220
1188
|
function runOpenFgaMigrate(config, runtimeEnv) {
|
|
1221
1189
|
logStep("Running OpenFGA datastore migrations");
|
|
1222
1190
|
if (currentOptions.dryRun) {
|
|
@@ -1351,13 +1319,24 @@ function runClickstackBootstrap(config) {
|
|
|
1351
1319
|
logCommand("node", [path.join(REPO_ROOT, "scripts/bootstrap-clickstack-selfhost.mjs")]);
|
|
1352
1320
|
return;
|
|
1353
1321
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1322
|
+
const deadline = Date.now() + 180 * 1e3;
|
|
1323
|
+
let lastError = "unknown error";
|
|
1324
|
+
while (Date.now() < deadline) {
|
|
1325
|
+
try {
|
|
1326
|
+
run("node", [path.join(REPO_ROOT, "scripts/bootstrap-clickstack-selfhost.mjs")], {
|
|
1327
|
+
env: {
|
|
1328
|
+
ENVSYNC_STACK_NAME: config.services.stack_name,
|
|
1329
|
+
ENVSYNC_ROOT_DOMAIN: config.domain.root_domain
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
logSuccess("ClickStack self-host bootstrap completed");
|
|
1333
|
+
return;
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
1336
|
+
sleepSeconds(3);
|
|
1358
1337
|
}
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1338
|
+
}
|
|
1339
|
+
throw new Error(`Timed out bootstrapping ClickStack: ${lastError}`);
|
|
1361
1340
|
}
|
|
1362
1341
|
function parseBootstrapInitJson(output) {
|
|
1363
1342
|
const trimmed = output.trim();
|
|
@@ -1685,7 +1664,7 @@ async function cmdBootstrap() {
|
|
|
1685
1664
|
waitForHttpService(config, "keycloak management readiness", "http://keycloak:9000/health/ready", 180);
|
|
1686
1665
|
waitForHttpService(config, "openfga", "http://openfga:8090/stores");
|
|
1687
1666
|
waitForTcpService(config, "minikms", "minikms", 50051);
|
|
1688
|
-
|
|
1667
|
+
waitForTcpService(config, "clickstack ui", "clickstack", 8080, 180);
|
|
1689
1668
|
const initResult = runBootstrapInit(config);
|
|
1690
1669
|
const persistedGenerated = normalizeGeneratedState({
|
|
1691
1670
|
openfga: {
|
|
@@ -1921,6 +1900,7 @@ async function cmdBackup() {
|
|
|
1921
1900
|
writeFile(path.join(staged, "traefik-dynamic.yaml"), fs.readFileSync(TRAEFIK_DYNAMIC_FILE, "utf8"));
|
|
1922
1901
|
writeFile(path.join(staged, "keycloak-realm.envsync.json"), fs.readFileSync(KEYCLOAK_REALM_FILE, "utf8"));
|
|
1923
1902
|
writeFile(path.join(staged, "otel-agent.yaml"), fs.readFileSync(OTEL_AGENT_CONF, "utf8"));
|
|
1903
|
+
writeFile(path.join(staged, "clickhouse-listen.xml"), fs.readFileSync(CLICKSTACK_CLICKHOUSE_CONF, "utf8"));
|
|
1924
1904
|
const volumesDir = path.join(staged, "volumes");
|
|
1925
1905
|
for (const volume of STACK_VOLUMES) {
|
|
1926
1906
|
backupDockerVolume(stackVolumeName(config, volume), path.join(volumesDir, volume));
|
|
@@ -1961,6 +1941,7 @@ async function cmdRestore(archivePath) {
|
|
|
1961
1941
|
writeFile(TRAEFIK_DYNAMIC_FILE, fs.readFileSync(path.join(restoreRoot, "traefik-dynamic.yaml"), "utf8"));
|
|
1962
1942
|
writeFile(KEYCLOAK_REALM_FILE, fs.readFileSync(path.join(restoreRoot, "keycloak-realm.envsync.json"), "utf8"));
|
|
1963
1943
|
writeFile(OTEL_AGENT_CONF, fs.readFileSync(path.join(restoreRoot, "otel-agent.yaml"), "utf8"));
|
|
1944
|
+
writeFile(CLICKSTACK_CLICKHOUSE_CONF, fs.readFileSync(path.join(restoreRoot, "clickhouse-listen.xml"), "utf8"));
|
|
1964
1945
|
const config = loadConfig();
|
|
1965
1946
|
for (const volume of STACK_VOLUMES) {
|
|
1966
1947
|
restoreDockerVolume(stackVolumeName(config, volume), path.join(restoreRoot, "volumes", volume));
|