@stacksjs/ts-cloud 0.7.81 → 0.7.83
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/bin/cli.js +398 -352
- package/dist/{chunk-5z0an6q8.js → chunk-838t87x3.js} +55 -9
- package/dist/{chunk-ng8hbbmy.js → chunk-ptf1hhsd.js} +41 -29
- package/dist/deploy/index.js +2 -2
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/shared/compute-deploy.d.ts +1 -1
- package/dist/drivers/shared/rpx-gateway.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/ui/access-denied.html +2 -2
- package/dist/ui/account/automation.html +3 -3
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +4 -4
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +4 -4
- package/dist/ui/data/services.html +4 -4
- package/dist/ui/data/volumes.html +4 -4
- package/dist/ui/index.html +4 -4
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +4 -4
- package/dist/ui/operations/configuration.html +4 -4
- package/dist/ui/operations/jobs.html +4 -4
- package/dist/ui/operations/maintenance.html +3 -3
- package/dist/ui/operations/observability.html +4 -4
- package/dist/ui/operations/previews.html +4 -4
- package/dist/ui/operations/queue.html +4 -4
- package/dist/ui/operations/regions.html +4 -4
- package/dist/ui/operations/releases.html +4 -4
- package/dist/ui/operations/workloads.html +4 -4
- package/dist/ui/security.html +2 -2
- package/dist/ui/server/actions.html +3 -3
- package/dist/ui/server/activity.html +2 -2
- package/dist/ui/server/capacity.html +4 -4
- package/dist/ui/server/database.html +4 -4
- package/dist/ui/server/deployments.html +4 -4
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +4 -4
- package/dist/ui/server/fleet.html +4 -4
- package/dist/ui/server/logs.html +4 -4
- package/dist/ui/server/metrics.html +4 -4
- package/dist/ui/server/services.html +2 -2
- package/dist/ui/server/sites.html +3 -3
- package/dist/ui/server/ssh-keys.html +4 -4
- package/dist/ui/server/team.html +4 -4
- package/dist/ui/serverless/alarms.html +4 -4
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +4 -4
- package/dist/ui/serverless/firewall.html +2 -2
- package/dist/ui/serverless/functions.html +4 -4
- package/dist/ui/serverless/logs.html +4 -4
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +4 -4
- package/dist/ui/serverless/secrets.html +4 -4
- package/dist/ui/serverless/traces.html +4 -4
- package/dist/ui/serverless.html +4 -4
- package/package.json +3 -3
|
@@ -399,10 +399,9 @@ function buildMonitoringScript(monitoring = true) {
|
|
|
399
399
|
"set -uo pipefail",
|
|
400
400
|
`LOAD=$(cut -d' ' -f1 /proc/loadavg)`,
|
|
401
401
|
"CPUS=$(nproc)",
|
|
402
|
-
`MEM_TOTAL
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
`SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')`,
|
|
402
|
+
`read MEM_TOTAL MEM_USED SWAP_TOTAL SWAP_USED <<EOF
|
|
403
|
+
$(free -m | awk '/^Mem:/{total=$2; used=$3} /^Swap:/{print total, used, $2, $3}')
|
|
404
|
+
EOF`,
|
|
406
405
|
`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,
|
|
407
406
|
`UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)`,
|
|
408
407
|
`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,
|
|
@@ -1112,7 +1111,7 @@ function buildRpxConfigInternal(sites, options, appBoxes) {
|
|
|
1112
1111
|
});
|
|
1113
1112
|
const config = {
|
|
1114
1113
|
proxies,
|
|
1115
|
-
productionCerts: { certsDir },
|
|
1114
|
+
productionCerts: { certsDir, certsDirServerNames: [...domains] },
|
|
1116
1115
|
https: true,
|
|
1117
1116
|
hostsManagement: false,
|
|
1118
1117
|
cleanup: { hosts: false, certs: false }
|
|
@@ -1221,7 +1220,13 @@ for (const f of files) {
|
|
|
1221
1220
|
}
|
|
1222
1221
|
const config = {
|
|
1223
1222
|
proxies,
|
|
1224
|
-
productionCerts: {
|
|
1223
|
+
productionCerts: {
|
|
1224
|
+
certsDir,
|
|
1225
|
+
// A shared host's cert directory also contains mail and retired-site PEMs.
|
|
1226
|
+
// Keep those files on disk for their owners, but do not turn them into live
|
|
1227
|
+
// OpenSSL SNI contexts when no current route can select them.
|
|
1228
|
+
certsDirServerNames: [...new Set(proxies.map(p => p.to).filter(Boolean))],
|
|
1229
|
+
},
|
|
1225
1230
|
https: true,
|
|
1226
1231
|
hostsManagement: false,
|
|
1227
1232
|
cleanup: { hosts: false, certs: false },
|
|
@@ -1390,7 +1395,10 @@ function buildRpxProvisionScript(options) {
|
|
|
1390
1395
|
`), "TS_CLOUD_RPX_UNIT_EOF"),
|
|
1391
1396
|
"systemctl daemon-reload",
|
|
1392
1397
|
"systemctl disable --now bun-gateway.service 2>/dev/null || true",
|
|
1398
|
+
"systemctl disable --now bun-gateway-renew.timer bun-gateway-renew.service 2>/dev/null || true",
|
|
1399
|
+
"rm -f /etc/systemd/system/bun-gateway-renew.timer /etc/systemd/system/bun-gateway-renew.service",
|
|
1393
1400
|
"systemctl disable --now ts-cloud-nginx.service 2>/dev/null || true",
|
|
1401
|
+
`for timer in /etc/systemd/system/rpx-cert-renew-*.timer; do [ -e "$timer" ] || continue; unit="$(basename "$timer")"; tenant="\${unit#rpx-cert-renew-}"; tenant="\${tenant%.timer}"; [ -f "${RPX_SITES_DIR}/$tenant.json" ] && continue; systemctl disable --now "$unit" 2>/dev/null || true; rm -f "$timer" "/etc/systemd/system/rpx-cert-renew-$tenant.service" "${RPX_DIR}/renew-certs-$tenant.sh"; done`,
|
|
1394
1402
|
`systemctl enable ${RPX_SERVICE_NAME}`,
|
|
1395
1403
|
`systemctl restart ${RPX_SERVICE_NAME}`,
|
|
1396
1404
|
...buildCertManagementCommands(options)
|
|
@@ -5757,9 +5765,46 @@ async function deploySiteRelease(driver, options, logger = noopLogger2) {
|
|
|
5757
5765
|
function shellSingleQuote(value) {
|
|
5758
5766
|
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
5759
5767
|
}
|
|
5760
|
-
function buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNames, serverOwner = false) {
|
|
5768
|
+
function buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNames, serverOwner = false, desiredDomains = []) {
|
|
5761
5769
|
const prefix = `${slug}-dashboard-`;
|
|
5762
5770
|
const desiredUnits = desiredSiteNames.map((siteName) => `${slug}-${siteName}.service`);
|
|
5771
|
+
const routeReconciliation = serverOwner ? [
|
|
5772
|
+
`export TS_CLOUD_DASHBOARD_KEEP_DOMAINS=${shellSingleQuote(JSON.stringify(desiredDomains))}`,
|
|
5773
|
+
"rm -f /run/ts-cloud-dashboard-routes-changed",
|
|
5774
|
+
`/usr/local/bin/bun --bun -e ${shellSingleQuote(`
|
|
5775
|
+
const { chmodSync, existsSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } = require('node:fs')
|
|
5776
|
+
const { basename, join } = require('node:path')
|
|
5777
|
+
const root = '/etc/rpx/sites.d'
|
|
5778
|
+
const keep = new Set(JSON.parse(process.env.TS_CLOUD_DASHBOARD_KEEP_DOMAINS || '[]'))
|
|
5779
|
+
let changed = false
|
|
5780
|
+
for (const name of existsSync(root) ? readdirSync(root) : []) {
|
|
5781
|
+
if (!name.endsWith('.json')) continue
|
|
5782
|
+
const file = join(root, name)
|
|
5783
|
+
let config
|
|
5784
|
+
try { config = JSON.parse(readFileSync(file, 'utf8')) } catch { continue }
|
|
5785
|
+
if (!Array.isArray(config.proxies)) continue
|
|
5786
|
+
const project = basename(name, '.json')
|
|
5787
|
+
const proxies = config.proxies.filter((route) => {
|
|
5788
|
+
const domain = typeof route?.to === 'string' ? route.to.toLowerCase() : ''
|
|
5789
|
+
if (!/^(?:dashboard|cloud)\\./.test(domain) || keep.has(domain)) return true
|
|
5790
|
+
const siteName = domain.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
|
|
5791
|
+
return !existsSync('/var/www/' + project + '-' + siteName)
|
|
5792
|
+
})
|
|
5793
|
+
if (proxies.length === config.proxies.length) continue
|
|
5794
|
+
const temporary = file + '.tmp-' + process.pid
|
|
5795
|
+
const mode = statSync(file).mode & 0o777
|
|
5796
|
+
writeFileSync(temporary, JSON.stringify({ ...config, proxies }, null, 2) + '\\n', { mode })
|
|
5797
|
+
chmodSync(temporary, mode)
|
|
5798
|
+
renameSync(temporary, file)
|
|
5799
|
+
changed = true
|
|
5800
|
+
}
|
|
5801
|
+
if (changed) writeFileSync('/run/ts-cloud-dashboard-routes-changed', '')
|
|
5802
|
+
`)}`,
|
|
5803
|
+
"if [ -e /run/ts-cloud-dashboard-routes-changed ]; then",
|
|
5804
|
+
" systemctl restart rpx-gateway.service",
|
|
5805
|
+
" rm -f /run/ts-cloud-dashboard-routes-changed",
|
|
5806
|
+
"fi"
|
|
5807
|
+
] : [];
|
|
5763
5808
|
return [
|
|
5764
5809
|
"set -euo pipefail",
|
|
5765
5810
|
`TS_CLOUD_DASHBOARD_PREFIX=${shellSingleQuote(prefix)}`,
|
|
@@ -5784,7 +5829,8 @@ function buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNa
|
|
|
5784
5829
|
" esac",
|
|
5785
5830
|
"done",
|
|
5786
5831
|
"systemctl daemon-reload",
|
|
5787
|
-
"systemctl reset-failed"
|
|
5832
|
+
"systemctl reset-failed",
|
|
5833
|
+
...routeReconciliation
|
|
5788
5834
|
];
|
|
5789
5835
|
}
|
|
5790
5836
|
async function reconcileManagementDashboardServices(driver, options, desiredSiteNames, logger) {
|
|
@@ -5796,7 +5842,7 @@ async function reconcileManagementDashboardServices(driver, options, desiredSite
|
|
|
5796
5842
|
return true;
|
|
5797
5843
|
const result = await driver.runRemoteDeploy({
|
|
5798
5844
|
targets,
|
|
5799
|
-
commands: buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNames, !config.cloud?.attachTo),
|
|
5845
|
+
commands: buildManagementDashboardServiceReconciliationScript(slug, desiredSiteNames, !config.cloud?.attachTo, desiredSiteNames.map((siteName) => config.sites?.[siteName]?.domain).filter((domain) => typeof domain === "string")),
|
|
5800
5846
|
comment: `ts-cloud reconcile management dashboard ${slug}`,
|
|
5801
5847
|
tags: {
|
|
5802
5848
|
Project: slug,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
resolveSiteKind,
|
|
46
46
|
resolveUiSource,
|
|
47
47
|
siteInstallBase
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-838t87x3.js";
|
|
49
49
|
import {
|
|
50
50
|
artifactKey,
|
|
51
51
|
buildCloudFormationTemplate,
|
|
@@ -38547,28 +38547,34 @@ for (const route of routes) console.log('DISCOVERED_SITE=' + Buffer.from(JSON.st
|
|
|
38547
38547
|
const serviceOutput = Bun.spawnSync([
|
|
38548
38548
|
'systemctl', 'list-units', '--type=service', '--state=running', '--no-legend', '--plain',
|
|
38549
38549
|
]).stdout.toString()
|
|
38550
|
-
|
|
38551
|
-
|
|
38552
|
-
|
|
38553
|
-
|
|
38550
|
+
const runningUnits = serviceOutput
|
|
38551
|
+
.split('\n')
|
|
38552
|
+
.map(line => line.trim().split(/\s+/)[0])
|
|
38553
|
+
.filter(Boolean)
|
|
38554
|
+
if (runningUnits.length > 0) {
|
|
38555
|
+
const propertiesOutput = Bun.spawnSync([
|
|
38554
38556
|
'systemctl',
|
|
38555
38557
|
'show',
|
|
38556
|
-
|
|
38557
|
-
'--property=WorkingDirectory,ExecStart,MemoryCurrent,UnitFileState,ActiveEnterTimestamp',
|
|
38558
|
+
...runningUnits,
|
|
38559
|
+
'--property=Id,WorkingDirectory,ExecStart,MemoryCurrent,UnitFileState,ActiveEnterTimestamp',
|
|
38558
38560
|
]).stdout.toString()
|
|
38559
|
-
const
|
|
38560
|
-
const
|
|
38561
|
-
|
|
38562
|
-
|
|
38563
|
-
|
|
38564
|
-
|
|
38565
|
-
|
|
38566
|
-
|
|
38567
|
-
|
|
38568
|
-
|
|
38569
|
-
|
|
38570
|
-
|
|
38571
|
-
|
|
38561
|
+
for (const properties of propertiesOutput.split(/\n\n+/)) {
|
|
38562
|
+
const values = Object.fromEntries(properties.split('\n').filter(Boolean).map(value => {
|
|
38563
|
+
const separator = value.indexOf('=')
|
|
38564
|
+
return separator < 0 ? [value, ''] : [value.slice(0, separator), value.slice(separator + 1)]
|
|
38565
|
+
}))
|
|
38566
|
+
const unit = values.Id
|
|
38567
|
+
if (!unit) continue
|
|
38568
|
+
if (!/^\/var\/www\/|^\/opt\/ts-cloud\//.test(values.WorkingDirectory || '') && !/\/var\/www\/|\/opt\/ts-cloud\//.test(values.ExecStart || '')) continue
|
|
38569
|
+
console.log([
|
|
38570
|
+
'SVC',
|
|
38571
|
+
unit,
|
|
38572
|
+
'active',
|
|
38573
|
+
values.MemoryCurrent || '0',
|
|
38574
|
+
values.UnitFileState || '-',
|
|
38575
|
+
values.ActiveEnterTimestamp || '-',
|
|
38576
|
+
].join('='))
|
|
38577
|
+
}
|
|
38572
38578
|
}
|
|
38573
38579
|
`;
|
|
38574
38580
|
return `echo '${Buffer.from(source).toString("base64")}' | base64 -d | bun -`;
|
|
@@ -38588,15 +38594,21 @@ EOF`,
|
|
|
38588
38594
|
`echo "LOAD=$(cut -d' ' -f1 /proc/loadavg 2>/dev/null || echo 0)"`,
|
|
38589
38595
|
`echo "LOAD5=$(cut -d' ' -f2 /proc/loadavg 2>/dev/null || echo 0)"`,
|
|
38590
38596
|
`echo "LOAD15=$(cut -d' ' -f3 /proc/loadavg 2>/dev/null || echo 0)"`,
|
|
38591
|
-
`
|
|
38592
|
-
|
|
38593
|
-
|
|
38594
|
-
|
|
38595
|
-
|
|
38596
|
-
|
|
38597
|
-
|
|
38598
|
-
|
|
38599
|
-
|
|
38597
|
+
`read MEMTOTAL MEMUSED MEMAVAILABLE MEMCACHE SWAPTOTAL SWAPUSED <<EOF
|
|
38598
|
+
$(free -m 2>/dev/null | awk '/^Mem:/{total=$2; used=$3; available=$7; cache=$6} /^Swap:/{print total, used, available, cache, $2, $3}')
|
|
38599
|
+
EOF`,
|
|
38600
|
+
'echo "MEMTOTAL=${MEMTOTAL:-0}"',
|
|
38601
|
+
'echo "MEMUSED=${MEMUSED:-0}"',
|
|
38602
|
+
'echo "MEMAVAILABLE=${MEMAVAILABLE:-0}"',
|
|
38603
|
+
'echo "MEMCACHE=${MEMCACHE:-0}"',
|
|
38604
|
+
'echo "SWAPTOTAL=${SWAPTOTAL:-0}"',
|
|
38605
|
+
'echo "SWAPUSED=${SWAPUSED:-0}"',
|
|
38606
|
+
`read DISKTOTG DISKUSEDG DISKPCT <<EOF
|
|
38607
|
+
$(df -BG -P / 2>/dev/null | awk 'NR==2{gsub("G","",$2); gsub("G","",$3); gsub("%","",$5); print $2, $3, $5}')
|
|
38608
|
+
EOF`,
|
|
38609
|
+
'echo "DISKPCT=${DISKPCT:-0}"',
|
|
38610
|
+
'echo "DISKUSEDG=${DISKUSEDG:-0}"',
|
|
38611
|
+
'echo "DISKTOTG=${DISKTOTG:-0}"',
|
|
38600
38612
|
`echo "INODEPCT=$(df -Pi / 2>/dev/null | awk 'NR==2{gsub("%","",$5);print $5}')"`,
|
|
38601
38613
|
`echo "NETRX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$3} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,
|
|
38602
38614
|
`echo "NETTX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$11} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,
|
package/dist/deploy/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
synchronizeDashboardUsers,
|
|
33
33
|
trackDashboardOperation,
|
|
34
34
|
verifyStaticApiOrigin
|
|
35
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-ptf1hhsd.js";
|
|
36
36
|
import {
|
|
37
37
|
deleteStaticSite,
|
|
38
38
|
deployStaticSite,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
shipsARelease,
|
|
66
66
|
siteInstallBase,
|
|
67
67
|
validateDeploymentConfig
|
|
68
|
-
} from "../chunk-
|
|
68
|
+
} from "../chunk-838t87x3.js";
|
|
69
69
|
import"../chunk-1qjyqrc5.js";
|
|
70
70
|
import"../chunk-703nkybg.js";
|
|
71
71
|
import"../chunk-4cjrg98a.js";
|
package/dist/drivers/index.js
CHANGED
|
@@ -42,7 +42,7 @@ export interface DeployAllSitesOptions {
|
|
|
42
42
|
* and can keep crash-looping on its old port. Release data and shared dashboard
|
|
43
43
|
* state stay on disk for recovery.
|
|
44
44
|
*/
|
|
45
|
-
export declare function buildManagementDashboardServiceReconciliationScript(slug: string, desiredSiteNames: string[], serverOwner?: boolean): string[];
|
|
45
|
+
export declare function buildManagementDashboardServiceReconciliationScript(slug: string, desiredSiteNames: string[], serverOwner?: boolean, desiredDomains?: string[]): string[];
|
|
46
46
|
/**
|
|
47
47
|
* Deploy every site that targets the compute server — both dynamic apps
|
|
48
48
|
* (`server` + `start`, run as systemd services) and static sites (`server`
|
package/dist/index.js
CHANGED
|
@@ -285,7 +285,7 @@ import {
|
|
|
285
285
|
volumeCapabilities,
|
|
286
286
|
webhookEndpoint,
|
|
287
287
|
zeroCapacity
|
|
288
|
-
} from "./chunk-
|
|
288
|
+
} from "./chunk-ptf1hhsd.js";
|
|
289
289
|
import {
|
|
290
290
|
deleteStaticSite,
|
|
291
291
|
deployStaticSite,
|
|
@@ -398,7 +398,7 @@ import {
|
|
|
398
398
|
waitForCloudInit,
|
|
399
399
|
waitForSsh,
|
|
400
400
|
wrapCloudInitUserData
|
|
401
|
-
} from "./chunk-
|
|
401
|
+
} from "./chunk-838t87x3.js";
|
|
402
402
|
import {
|
|
403
403
|
ABTestManager,
|
|
404
404
|
AI,
|