@stacksjs/ts-cloud 0.7.92 → 0.7.94

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.
Files changed (69) hide show
  1. package/dist/bin/cli.js +1235 -1183
  2. package/dist/bin/dashboard-server.js +451 -399
  3. package/dist/{chunk-29fwqkb7.js → chunk-0htae1c2.js} +456 -21
  4. package/dist/{chunk-fbwcv2vf.js → chunk-bs3jfnzp.js} +451 -41
  5. package/dist/control-plane/store.d.ts +1 -0
  6. package/dist/deploy/dashboard-database.d.ts +91 -3
  7. package/dist/deploy/dashboard-vitess.d.ts +154 -0
  8. package/dist/deploy/dashboard-vitess.test.d.ts +1 -0
  9. package/dist/deploy/index.js +2 -2
  10. package/dist/drivers/hetzner/client.d.ts +96 -0
  11. package/dist/drivers/hetzner/migrate-server.d.ts +124 -0
  12. package/dist/drivers/hetzner/migrate-server.test.d.ts +1 -0
  13. package/dist/drivers/hetzner/role-swap.d.ts +139 -0
  14. package/dist/drivers/hetzner/role-swap.test.d.ts +1 -0
  15. package/dist/drivers/index.js +1 -1
  16. package/dist/drivers/shared/db-provision.d.ts +4 -0
  17. package/dist/drivers/shared/deploy-script.d.ts +17 -1
  18. package/dist/drivers/shared/package-manager.d.ts +2 -0
  19. package/dist/drivers/shared/releases.d.ts +41 -2
  20. package/dist/drivers/shared/vitess-provision.d.ts +133 -0
  21. package/dist/drivers/shared/vitess-provision.test.d.ts +1 -0
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.js +6 -2
  24. package/dist/telemetry/store.d.ts +1 -0
  25. package/dist/ui/account/automation.html +4 -4
  26. package/dist/ui/account/security.html +2 -2
  27. package/dist/ui/applications/compose.html +4 -4
  28. package/dist/ui/data/backups.html +4 -4
  29. package/dist/ui/data/services.html +4 -4
  30. package/dist/ui/data/volumes.html +3 -3
  31. package/dist/ui/index.html +4 -4
  32. package/dist/ui/integrations.html +2 -2
  33. package/dist/ui/operations/alerts.html +4 -4
  34. package/dist/ui/operations/configuration.html +4 -4
  35. package/dist/ui/operations/jobs.html +4 -4
  36. package/dist/ui/operations/maintenance.html +3 -3
  37. package/dist/ui/operations/observability.html +4 -4
  38. package/dist/ui/operations/previews.html +4 -4
  39. package/dist/ui/operations/queue.html +4 -4
  40. package/dist/ui/operations/regions.html +4 -4
  41. package/dist/ui/operations/releases.html +4 -4
  42. package/dist/ui/operations/workloads.html +4 -4
  43. package/dist/ui/security.html +2 -2
  44. package/dist/ui/server/actions.html +4 -4
  45. package/dist/ui/server/activity.html +2 -2
  46. package/dist/ui/server/capacity.html +4 -4
  47. package/dist/ui/server/database.html +124 -8
  48. package/dist/ui/server/deployments.html +4 -4
  49. package/dist/ui/server/diagnostics.html +2 -2
  50. package/dist/ui/server/firewall.html +4 -4
  51. package/dist/ui/server/fleet.html +4 -4
  52. package/dist/ui/server/logs.html +4 -4
  53. package/dist/ui/server/metrics.html +4 -4
  54. package/dist/ui/server/services.html +2 -2
  55. package/dist/ui/server/sites.html +4 -4
  56. package/dist/ui/server/ssh-keys.html +4 -4
  57. package/dist/ui/server/team.html +4 -4
  58. package/dist/ui/server/terminal.html +2 -2
  59. package/dist/ui/serverless/alarms.html +4 -4
  60. package/dist/ui/serverless/data.html +3 -3
  61. package/dist/ui/serverless/firewall.html +2 -2
  62. package/dist/ui/serverless/functions.html +4 -4
  63. package/dist/ui/serverless/logs.html +4 -4
  64. package/dist/ui/serverless/queues.html +4 -4
  65. package/dist/ui/serverless/secrets.html +4 -4
  66. package/dist/ui/serverless/traces.html +4 -4
  67. package/dist/ui/serverless.html +3 -3
  68. package/dist/ui-src/pages/server/database.stx +257 -9
  69. package/package.json +3 -3
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Swapping the roles of two servers.
3
+ *
4
+ * The situation this exists for: a server type is no longer obtainable. Hetzner
5
+ * retires older lines, and `available_for_migration` goes false everywhere, so
6
+ * a `change_type` onto that type can never succeed again. If you already own an
7
+ * instance of it, that instance is the only one you will ever have — and the
8
+ * right move is to put your heaviest workload on it rather than to keep trying
9
+ * to buy another.
10
+ *
11
+ * A resize cannot do this. What can is exchanging the two servers' primary IPs,
12
+ * so each address keeps pointing at the workload that answers on it, with no
13
+ * DNS change and no waiting on propagation.
14
+ *
15
+ * Two constraints decide whether it is possible at all, and both are cheap to
16
+ * check before anything is powered off:
17
+ *
18
+ * - A primary IP belongs to a datacenter. Two servers in different
19
+ * datacenters cannot exchange addresses, and finding that out halfway
20
+ * through leaves both boxes down with their addresses detached.
21
+ * - Data has to fit. Moving a workload onto a smaller disk fails at restore
22
+ * time, which is the worst moment to discover it.
23
+ *
24
+ * The planning is pure so those rules can be tested without an account.
25
+ *
26
+ * IMPORTANT, and not yet handled here: exchanging addresses does not move the
27
+ * workload. Each disk keeps the software and data it already had, so a swap on
28
+ * its own points every address at the wrong application. A complete role swap
29
+ * is three phases - deploy each workload onto its new host, restore its data,
30
+ * and only then exchange the addresses - and this module plans the third.
31
+ * `planRoleSwap` deliberately refuses to look like the whole job.
32
+ */
33
+ export interface SwapServer {
34
+ id: number;
35
+ name: string;
36
+ /**
37
+ * Where the server sits, for the purpose of deciding whether an address can
38
+ * move to it. Derive it with {@link placementOf} rather than reading a field
39
+ * off the API response, and see that function for why. Null when unknown,
40
+ * which is a blocker rather than a pass.
41
+ */
42
+ placement: string | null;
43
+ serverType: string;
44
+ diskSizeGb: number;
45
+ /** Bytes actually in use, so a move onto a smaller disk can be refused early. */
46
+ usedGb: number;
47
+ primaryIpId: number | null;
48
+ primaryIp: string | null;
49
+ }
50
+ export type SwapStepKind = 'power-off' | 'unassign-ip' | 'assign-ip' | 'power-on' | 'rename';
51
+ export interface SwapStep {
52
+ kind: SwapStepKind;
53
+ serverId: number;
54
+ /** For an IP step, the address being moved. */
55
+ ipId?: number;
56
+ /** For a rename, the name to take. */
57
+ name?: string;
58
+ description: string;
59
+ }
60
+ export interface SwapPlan {
61
+ ok: boolean;
62
+ /** Why the swap cannot proceed. Empty when it can. */
63
+ blockers: string[];
64
+ steps: SwapStep[];
65
+ }
66
+ /**
67
+ * Whether a workload fits on the other server's disk.
68
+ *
69
+ * A margin is kept rather than comparing raw numbers: a disk that is exactly
70
+ * full is a disk that fails on the next write, and a restore needs room for
71
+ * both the archive and its expansion.
72
+ */
73
+ export declare function fits(usedGb: number, targetDiskGb: number, marginRatio?: number): boolean;
74
+ /**
75
+ * Where a server sits, from whichever field the API still reports.
76
+ *
77
+ * Primary IPs are bound at datacenter granularity, so `datacenter` is the
78
+ * field this wants. The API has stopped returning it — `datacenter` is now
79
+ * null on both the server and the primary IP, leaving only `location`.
80
+ *
81
+ * Reading the missing field directly is worse than useless: two servers in
82
+ * different datacenters both report `undefined`, `undefined === undefined`,
83
+ * and the guard that exists to stop a cross-datacenter swap waves it through.
84
+ * The failure then lands halfway, with both boxes off and their addresses
85
+ * detached, which is the exact outcome the check was written to prevent.
86
+ *
87
+ * So: prefer the datacenter when present, fall back to the location, and
88
+ * return null when neither is known so the caller can refuse. Location is a
89
+ * sound proxy today because every Hetzner location contains exactly one
90
+ * datacenter; if that ever stops being true, this returns the coarser answer
91
+ * and the assign call is the backstop.
92
+ */
93
+ export declare function placementOf(server: {
94
+ datacenter?: {
95
+ name?: string;
96
+ } | null;
97
+ location?: {
98
+ name?: string;
99
+ } | null;
100
+ }): string | null;
101
+ /**
102
+ * The parking name one server wears while the other takes its name.
103
+ *
104
+ * Hetzner rejects a duplicate server name, so the two cannot cross directly.
105
+ */
106
+ export declare function swapTempName(name: string): string;
107
+ /**
108
+ * The ordered steps to exchange two servers' addresses and names.
109
+ *
110
+ * Both are powered off before either address moves. Hetzner refuses to detach a
111
+ * primary IP from a running server, and doing them one at a time would leave
112
+ * the first server up with no address — reachable by nobody and, worse, still
113
+ * accepting work it can no longer be reached about.
114
+ */
115
+ export declare function planRoleSwap(a: SwapServer, b: SwapServer): SwapPlan;
116
+ /**
117
+ * Whether a type can still be migrated onto in a datacenter.
118
+ *
119
+ * `available` answers a different question — whether a NEW server of that type
120
+ * can be created — and reading it instead is why a doomed `change_type` looks
121
+ * like bad luck rather than a retired type. `available_for_migration` is the
122
+ * one `change_type` consults.
123
+ */
124
+ export declare function canMigrateTo(datacenter: {
125
+ server_types?: {
126
+ available_for_migration?: number[];
127
+ };
128
+ }, serverTypeId: number): boolean;
129
+ /**
130
+ * The advice to print when a resize is impossible.
131
+ *
132
+ * A type that is unobtainable everywhere is not a capacity blip to retry
133
+ * through; it is retired, and the instance you hold is the last one you get.
134
+ */
135
+ export declare function resizeAdvice(input: {
136
+ targetType: string;
137
+ migratableAnywhere: boolean;
138
+ ownedInstances: number;
139
+ }): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -68,7 +68,7 @@ import {
68
68
  waitForSsh,
69
69
  wrapCloudInitUserData,
70
70
  writeResizeCheckpoint
71
- } from "../chunk-fbwcv2vf.js";
71
+ } from "../chunk-bs3jfnzp.js";
72
72
  import"../chunk-hmehkeqx.js";
73
73
  import"../chunk-7m60qnc8.js";
74
74
  import"../chunk-4cjrg98a.js";
@@ -15,6 +15,10 @@ import type { ComputeServicesConfig, DatabaseConfig } from '@ts-cloud/core';
15
15
  * True when the database is co-located with the box (the managed-services
16
16
  * engine): no host configured, or an explicit loopback host. Anything else is
17
17
  * an external/managed database reached over TCP.
18
+ *
19
+ * An always-external engine is never local regardless of host — pointing one
20
+ * at 127.0.0.1 means a tunnel or a local proxy, not an engine this box
21
+ * installed and can administer over a unix socket.
18
22
  */
19
23
  export declare function isLocalDatabase(database: DatabaseConfig | undefined): boolean;
20
24
  /**
@@ -1,3 +1,16 @@
1
+ /**
2
+ * Shared deploy script helpers for Forge-style compute deploys.
3
+ *
4
+ * Both server-app and server-static sites deploy with **zero downtime** the same
5
+ * way PHP/Laravel sites do (Envoyer-style): the artifact is unpacked into a fresh
6
+ * `releases/<id>` directory, shared paths (`.env`) are symlinked in, and the
7
+ * `current` symlink is repointed atomically (`mv -Tf`). The gateway serves the
8
+ * site from `<base>/current`, so a static swap is instantaneous (no window where
9
+ * the docroot is empty), and an app restart re-execs against the already-staged
10
+ * release (no window where the code is half-replaced). Old releases are kept for
11
+ * instant rollback. See {@link import('./releases')}.
12
+ */
13
+ import type { SharedPathEntry } from '@ts-cloud/core';
1
14
  /**
2
15
  * Translate a `start` command (e.g. "bun run server.ts") into an absolute
3
16
  * systemd ExecStart by swapping the leading runtime word for its absolute path.
@@ -30,8 +43,11 @@ export interface BuildSiteDeployScriptOptions {
30
43
  * survive a deploy. `.env` is always shared; anything the app WRITES and must
31
44
  * keep (a state directory, a database file) has to be listed here or the next
32
45
  * release silently starts from empty.
46
+ *
47
+ * A `SharedPathSpec` entry points somewhere other than this site's own
48
+ * `shared/` — how several sites of one project share one file.
33
49
  */
34
- sharedPaths?: readonly string[];
50
+ sharedPaths?: readonly SharedPathEntry[];
35
51
  /**
36
52
  * True zero-downtime cutover for ported sites: the new release runs as its
37
53
  * own systemd instance (`<slug>-<site>@<releaseId>`) that binds the same
@@ -27,6 +27,8 @@ export declare const PANTRY_PACKAGES: {
27
27
  readonly mysql: 'mysql.com';
28
28
  readonly mariadb: 'mariadb.com/server';
29
29
  readonly postgres: 'postgresql.org';
30
+ readonly vitess: 'vitess.io';
31
+ readonly etcd: 'etcd.io';
30
32
  readonly redis: 'redis.io';
31
33
  readonly memcached: 'memcached.org';
32
34
  readonly meilisearch: 'meilisearch.com';
@@ -12,6 +12,7 @@
12
12
  * $CREATE_RELEASE → {@link buildEnsureReleaseLayout} + git clone + {@link buildLinkSharedPaths}
13
13
  * $ACTIVATE_RELEASE → {@link buildActivateRelease} (+ {@link buildPruneReleases})
14
14
  */
15
+ import type { SharedPathEntry } from '@ts-cloud/core';
15
16
  /** Paths that are always shared across releases (Forge shares `.env` implicitly). */
16
17
  export declare const DEFAULT_SHARED_PATHS: readonly string[];
17
18
  /** Default number of past releases to retain for rollback. */
@@ -24,6 +25,13 @@ export declare function deployMetaDir(base: string): string;
24
25
  export declare function deployHistoryPath(base: string): string;
25
26
  /** Per-deploy output log path for a release. */
26
27
  export declare function deployLogPath(base: string, releaseId: string): string;
28
+ /**
29
+ * Manifest of the shared paths the last deploy declared, written on every deploy
30
+ * so a rollback can relink them into an older release without knowing the site's
31
+ * config. Lives beside the deploy history (outside `releases/`, so pruning a
32
+ * release never takes it).
33
+ */
34
+ export declare function sharedPathsManifestPath(base: string): string;
27
35
  export interface ReleasePaths {
28
36
  /** Site base directory (`/var/www/<site>`). */
29
37
  base: string;
@@ -38,11 +46,25 @@ export interface ReleasePaths {
38
46
  }
39
47
  /** Resolve the standard release layout paths for a site + release id. */
40
48
  export declare function releasePaths(base: string, releaseId: string): ReleasePaths;
49
+ /** The release-relative path an entry links, whichever form it takes. */
50
+ export declare function sharedPathOf(entry: SharedPathEntry): string;
51
+ /**
52
+ * One entry per release-relative path, last declaration winning — so a site
53
+ * that spells out `{ path: '.env', target: … }` overrides the implicit `.env`
54
+ * rather than fighting it. A plain `new Set` cannot do this: two specs for the
55
+ * same path are distinct objects.
56
+ */
57
+ export declare function dedupeSharedPaths(entries: readonly SharedPathEntry[]): SharedPathEntry[];
41
58
  /**
42
59
  * Ensure the releases/ and shared/ skeleton exist, including the Laravel
43
60
  * `storage` tree and an empty shared `.env` so symlinks never dangle.
61
+ *
62
+ * Also adopts any pre-existing live copy of a newly-shared path (see
63
+ * {@link buildAdoptSharedPathFn}) and records the shared-path list in
64
+ * {@link sharedPathsManifestPath}, so {@link buildRollbackScript} can relink an
65
+ * older release at the same shared state.
44
66
  */
45
- export declare function buildEnsureReleaseLayout(paths: ReleasePaths, sharedPaths?: readonly string[]): string[];
67
+ export declare function buildEnsureReleaseLayout(paths: ReleasePaths, sharedPaths?: readonly SharedPathEntry[]): string[];
46
68
  /**
47
69
  * Take the site's deploy lock for the rest of the script.
48
70
  *
@@ -101,7 +123,18 @@ export declare function buildPromoteStagedRelease(paths: ReleasePaths): string[]
101
123
  * Symlink every shared path from `shared/` into the freshly checked-out release,
102
124
  * replacing whatever the checkout shipped (e.g. the repo's empty `storage`).
103
125
  */
104
- export declare function buildLinkSharedPaths(paths: ReleasePaths, sharedPaths?: readonly string[]): string[];
126
+ export declare function buildLinkSharedPaths(paths: ReleasePaths, sharedPaths?: readonly SharedPathEntry[]): string[];
127
+ /**
128
+ * The same links as {@link buildLinkSharedPaths}, but for a release that is
129
+ * already on disk and a shared-path list read from the box's manifest rather
130
+ * than from config. `releaseExpr` is a shell expression for the release dir.
131
+ *
132
+ * Used by rollback: a release cut before a path became shared still holds its
133
+ * own real copy there, so activating it would quietly swap the live state (the
134
+ * database) for that release's stale snapshot. A no-op on a box with no
135
+ * manifest — one that has never deployed a shared path.
136
+ */
137
+ export declare function buildRelinkSharedPaths(paths: ReleasePaths, releaseExpr: string): string[];
105
138
  /**
106
139
  * Atomically repoint `current` at the new release. Writes a temp symlink and
107
140
  * `mv -T`s it over `current` so there is no window where `current` is missing.
@@ -114,6 +147,12 @@ export declare function buildActivateRelease(paths: ReleasePaths): string[];
114
147
  * -T`), and a no-op-safe guard fails loudly if the target is missing rather than
115
148
  * leaving `current` dangling.
116
149
  *
150
+ * Before the flip, every shared path recorded on the box is relinked into the
151
+ * target release ({@link buildRelinkSharedPaths}) so a rollback moves the CODE
152
+ * back without moving the DATA back — a release cut before a path became shared
153
+ * still carries its own copy, and going live with it would silently swap the
154
+ * database for a stale snapshot.
155
+ *
117
156
  * With `unitBase` set (e.g. `myapp-api`), the script also swaps the running
118
157
  * systemd release instance for sites deployed zero-downtime style (templated
119
158
  * `<unitBase>@<releaseId>` units pinned to their release dirs): it starts the
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Vitess provisioning.
3
+ *
4
+ * Two modes, because "run Vitess" means two very different things depending on
5
+ * why you are doing it:
6
+ *
7
+ * - **`combo`** runs the entire stack inside a single `vtcombo` process with
8
+ * an in-memory topology. It is the right answer for development and CI: one
9
+ * unit, one port, nothing to bootstrap, and it goes away cleanly. It is not
10
+ * durable and must never be used for real data.
11
+ * - **`cluster`** runs the real daemons (etcd, vtctld, vttablet beside a
12
+ * managed mysqld, vtgate) as separate systemd units on the box, with the
13
+ * ordering and topology bootstrap they require.
14
+ *
15
+ * ## What cluster mode is and is not
16
+ *
17
+ * This provisions a **single-box** Vitess: every component on one machine.
18
+ * That is a genuine deployment for staging, small production, and any case
19
+ * where you want Vitess's online DDL and query routing without yet needing
20
+ * horizontal scale. It is deliberately NOT a multi-box sharded cluster:
21
+ * spreading tablets across machines means per-shard placement, cross-box
22
+ * topology, and reparent policy, which are decisions an operator has to make
23
+ * rather than defaults a provisioner should invent.
24
+ *
25
+ * So a sharded keyspace here has its shards' tablets on one host. That gives
26
+ * you the routing and DDL semantics of Vitess and none of the fault
27
+ * tolerance, which is the honest trade and is stated in the config docs.
28
+ *
29
+ * ## Ordering is the whole problem
30
+ *
31
+ * Vitess daemons are not independent. vtctld and vttablet both need the
32
+ * topology store; vttablet also needs its mysqld; vtgate needs topology to
33
+ * route. Starting them in the wrong order does not fail cleanly - components
34
+ * retry, so a mis-ordered stack comes up "green" and then behaves oddly under
35
+ * load. The units below encode the dependency graph in `After=`/`Requires=`
36
+ * so systemd enforces it rather than relying on retry luck.
37
+ */
38
+ import type { VitessKeyspaceConfig, VitessServiceConfig } from '@ts-cloud/core';
39
+ import type { PantrySpec } from './package-manager';
40
+ /** Where pantry exposes installed binaries. */
41
+ export declare const PANTRY_BIN: string;
42
+ /** vtgate's MySQL-protocol port. Applications connect here. */
43
+ export declare const VTGATE_MYSQL_PORT = 15306;
44
+ /** vtgate's gRPC port. */
45
+ export declare const VTGATE_GRPC_PORT = 15991;
46
+ /** vtctld's gRPC port. `vtctldclient --server` targets this. */
47
+ export declare const VTCTLD_GRPC_PORT = 15999;
48
+ /** vttablet's gRPC port. */
49
+ export declare const VTTABLET_GRPC_PORT = 16101;
50
+ /** Where etcd listens for the topology store. */
51
+ export declare const ETCD_CLIENT_PORT = 2379;
52
+ /** Root directory for Vitess state on the box. */
53
+ export declare const VITESS_ROOT = "/var/lib/vitess";
54
+ /**
55
+ * Tablet UID for the single-box tablet.
56
+ *
57
+ * Shared by mysqlctld and vttablet on purpose: they must agree, because
58
+ * Vitess derives the tablet's working directory (and therefore its mysqld
59
+ * socket) from `$VTDATAROOT/vt_<uid>`. Two different values silently give
60
+ * the tablet a mysqld it cannot find.
61
+ */
62
+ export declare const VITESS_TABLET_UID = 100;
63
+ /** Re-exported so callers of the provisioner need only one import. */
64
+ export type { VitessKeyspaceConfig, VitessServiceConfig };
65
+ export declare function enabled(value: boolean | VitessServiceConfig | undefined): value is true | VitessServiceConfig;
66
+ /** Packages a Vitess box needs, given the mode and whether etcd is external. */
67
+ export declare function vitessPackages(config: VitessServiceConfig): PantrySpec[];
68
+ /**
69
+ * The unprivileged account every Vitess daemon runs as.
70
+ *
71
+ * Not a hardening nicety: Vitess refuses to start as root outright
72
+ * ("running this as root makes no sense" from servenv.Init), so a unit with
73
+ * no `User=` crash-loops immediately on every daemon.
74
+ */
75
+ export declare const VITESS_USER = "vitess";
76
+ /** Directory holding the generated launcher scripts. */
77
+ export declare const VITESS_LIB = "/usr/local/lib/vitess";
78
+ /** The launcher scripts recorded so far, for inspection and testing. */
79
+ export declare function buildLaunchers(): Map<string, string>;
80
+ /**
81
+ * The single-process development stack.
82
+ *
83
+ * `vtcombo` runs vtgate, vttablet, and vtctld together against an in-memory
84
+ * topology, so there is nothing to order and nothing to bootstrap. The
85
+ * keyspaces are declared on the command line and exist from the first start.
86
+ */
87
+ export declare function buildVtcomboUnit(config: VitessServiceConfig): string;
88
+ /** etcd, the topology store every real Vitess component reads. */
89
+ export declare function buildEtcdUnit(): string;
90
+ /** vtctld: the control plane `vtctldclient` talks to. */
91
+ export declare function buildVtctldUnit(config: VitessServiceConfig): string;
92
+ /** vttablet: manages one mysqld and serves its shard. */
93
+ export declare function buildVttabletUnit(config: VitessServiceConfig, keyspace: string, shard: string): string;
94
+ /** mysqlctld: the managed mysqld a tablet owns. */
95
+ export declare function buildMysqlctldUnit(config: VitessServiceConfig): string;
96
+ /** Where the generated vtgate credentials live. */
97
+ export declare const VITESS_AUTH_FILE = "/etc/vitess/auth.json";
98
+ /**
99
+ * vtgate's static credentials file.
100
+ *
101
+ * vtgate defaults to `--mysql-auth-server-impl static` and exits with "no
102
+ * AuthServer name static registered" when no credentials are supplied, so
103
+ * this is required, not optional. The alternative Vitess offers is
104
+ * `none`, which would leave an unauthenticated MySQL endpoint - acceptable
105
+ * only for the loopback-bound combo stack, never for a cluster.
106
+ */
107
+ export declare function buildVitessAuthFileScript(config: VitessServiceConfig): string[];
108
+ /** vtgate: the query router applications connect to. */
109
+ export declare function buildVtgateUnit(config: VitessServiceConfig): string;
110
+ /**
111
+ * Bootstrap the topology: register the cell, then create each keyspace.
112
+ *
113
+ * Idempotent. `AddCellInfo` and `CreateKeyspace` both fail when the object
114
+ * already exists, and a re-provision must not turn that into a failed deploy,
115
+ * so each is guarded on the corresponding read.
116
+ */
117
+ export declare function buildVitessBootstrapScript(config: VitessServiceConfig): string[];
118
+ /**
119
+ * Wait until vtgate actually answers on its MySQL port.
120
+ *
121
+ * The deploy should fail here rather than later: a box that finished
122
+ * provisioning with a vtgate that never came up will accept a deploy and then
123
+ * fail every request, which is much harder to attribute.
124
+ */
125
+ export declare function buildVitessHealthCheck(config: VitessServiceConfig): string[];
126
+ /**
127
+ * Full provisioning script for a Vitess box.
128
+ *
129
+ * Order matters and is deliberate: install, write every unit, reload systemd
130
+ * ONCE, then start in dependency order, then bootstrap, then health-gate.
131
+ * Reloading per-unit would make systemd act on a half-written stack.
132
+ */
133
+ export declare function buildVitessProvisionScript(value: boolean | VitessServiceConfig | undefined): string[];
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -33,7 +33,7 @@ export { deployStaticSite, deployStaticSiteFull, uploadStaticFiles, invalidateCa
33
33
  export { collectServerDnsDomains, hostAcceptsIpv6, IPV6_EXCLUDED_HOST_LABELS, normalizePublicIpv6, reconcileAddressRecords, removeStaleServerAddressRecords, verifyAddressRecord, } from './deploy/server-dns';
34
34
  export type { AddressRecordReport } from './deploy/server-dns';
35
35
  export type { EnsureDashboardLogger, ResolvedDashboardAuth, StaticSiteConfig, DeployResult, UploadOptions, ExternalDnsStaticSiteConfig, ExternalDnsDeployResult, DeploySiteConfig, DeploySiteResult, StaticSiteDnsProvider, SiteDeployKind, DeploymentValidationResult, BuildImageOptions, BuiltImage, CodeSource, DeployServerlessOptions, ResolvedContext, } from './deploy';
36
- export { createCloudDriver, CloudDriverFactory, cloudDrivers, AwsDriver, HetznerDriver, HetznerClient, resolveHetznerApiToken, normalizeSshPublicKey, ensureFirewall, ensureServer, ensureSshKey, serverPublicIpv4, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, buildSshArgs, generateUbuntuAppCloudInit, wrapCloudInitUserData, buildHostCleanupScript, buildSiteDeployScript, buildStaticSiteDeployScript, resolveExecStart, deployAllComputeSites, deploySiteRelease, } from './drivers';
36
+ export { createCloudDriver, CloudDriverFactory, cloudDrivers, AwsDriver, HetznerDriver, HetznerClient, resolveHetznerApiToken, normalizeSshPublicKey, ensureFirewall, ensureServer, ensureSshKey, serverPublicIpv4, sshExec, sshExecOrThrow, scpUpload, waitForSsh, waitForCloudInit, buildSshArgs, generateUbuntuAppCloudInit, wrapCloudInitUserData, buildHostCleanupScript, buildSiteDeployScript, buildStaticSiteDeployScript, resolveExecStart, deployAllComputeSites, deploySiteRelease, reloadRpxGateway, renewRpxCertificates, } from './drivers';
37
37
  export type { CreateCloudDriverOptions } from './drivers/factory';
38
38
  export { dashboardActions, resolveDashboardAction, sanitizeCloudConfig, startLocalDashboardServer, } from './deploy/local-dashboard-server';
39
39
  export type { DashboardAction, LocalDashboardServer, LocalDashboardServerOptions, } from './deploy/local-dashboard-server';
package/dist/index.js CHANGED
@@ -283,7 +283,7 @@ import {
283
283
  volumeCapabilities,
284
284
  webhookEndpoint,
285
285
  zeroCapacity
286
- } from "./chunk-29fwqkb7.js";
286
+ } from "./chunk-0htae1c2.js";
287
287
  import {
288
288
  deleteStaticSite,
289
289
  deployStaticSite,
@@ -387,7 +387,9 @@ import {
387
387
  normalizePublicIpv6,
388
388
  normalizeSshPublicKey,
389
389
  reconcileAddressRecords,
390
+ reloadRpxGateway,
390
391
  removeStaleServerAddressRecords,
392
+ renewRpxCertificates,
391
393
  resolveDashboardAuth,
392
394
  resolveExecStart,
393
395
  resolveHetznerApiToken,
@@ -403,7 +405,7 @@ import {
403
405
  waitForCloudInit,
404
406
  waitForSsh,
405
407
  wrapCloudInitUserData
406
- } from "./chunk-fbwcv2vf.js";
408
+ } from "./chunk-bs3jfnzp.js";
407
409
  import {
408
410
  ABTestManager,
409
411
  AI,
@@ -5254,11 +5256,13 @@ export {
5254
5256
  requiresReplacement,
5255
5257
  requestHash,
5256
5258
  replicaManager,
5259
+ renewRpxCertificates,
5257
5260
  renderServerCron,
5258
5261
  renderComposeTemplate,
5259
5262
  removeStaleServerAddressRecords,
5260
5263
  removeSourceWebhook,
5261
5264
  remapKey,
5265
+ reloadRpxGateway,
5262
5266
  releaseTrafficPlan,
5263
5267
  releaseStrategyCapabilities,
5264
5268
  regionPairManager,
@@ -31,4 +31,5 @@ export declare class TelemetryStore {
31
31
  compacted: number;
32
32
  rollups: number;
33
33
  };
34
+ private rebuildStatusRollups;
34
35
  }