@underpostnet/cyberia 3.2.90 → 3.3.0
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/.env.example +16 -0
- package/.github/workflows/coverall.cyberia.ci.yml +87 -0
- package/.github/workflows/cyberia-client.cd.yml +1 -18
- package/.github/workflows/cyberia-server.cd.yml +1 -18
- package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
- package/.github/workflows/engine-cyberia.cd.yml +3 -78
- package/.github/workflows/ghpkg.ci.yml +7 -1
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -16
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +1 -9
- package/CHANGELOG.md +110 -1
- package/CLI-HELP.md +139 -9
- package/Dockerfile +1 -1
- package/Dockerfile.dev +1 -1
- package/Dockerfile.test +1 -1
- package/bin/build.js +7 -5
- package/bin/cyberia.js +73 -53
- package/bin/deploy.js +1 -1
- package/bin/index.js +73 -53
- package/compose.env +16 -0
- package/conf.js +2 -0
- package/deploy/dd-cyberia/deploy.sh +42 -0
- package/deploy/dd-cyberia/init.sh +63 -0
- package/deploy/dd-cyberia/sync-deploy.sh +194 -0
- package/deploy/lib/logging.sh +96 -0
- package/deploy/pwa-microservices-template/deploy.sh +72 -0
- package/deploy/release/deploy.sh +62 -0
- package/deployment.yaml +1 -1
- package/docker-compose.yml +31 -37
- package/hardhat/package-lock.json +9 -9
- package/hardhat/package.json +3 -3
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +5 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +52 -0
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/package.json +2 -2
- package/scripts/audit-selinux.sh +64 -0
- package/scripts/coverall-test-cyberia.sh +24 -0
- package/scripts/coverall-test.sh +24 -0
- package/scripts/gpu-diag.sh +0 -0
- package/scripts/ip-info.sh +0 -0
- package/scripts/k3s-node-setup.sh +18 -15
- package/scripts/kubeadm-node-setup.sh +12 -23
- package/scripts/link-local-underpost-cli.sh +0 -0
- package/scripts/lxd-vm-setup.sh +0 -0
- package/scripts/maas-nat-firewalld.sh +0 -0
- package/scripts/nat-iptables.sh +2 -0
- package/scripts/rhel-grpc-setup.sh +0 -0
- package/scripts/rocky-kickstart.sh +25 -9
- package/scripts/test-monitor.sh +1 -1
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +63 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +8 -1
- package/src/api/cyberia-instance/cyberia-instance.controller.js +3 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +13 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +43 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +1 -0
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +16 -3
- package/src/api/object-layer/object-layer.model.js +204 -3
- package/src/api/object-layer/object-layer.service.js +1 -14
- package/src/cli/baremetal.js +1 -2
- package/src/cli/cloud-init.js +1 -1
- package/src/cli/cluster.js +73 -68
- package/src/cli/db.js +9 -2
- package/src/cli/deploy.js +21 -5
- package/src/cli/docker-compose.js +1 -1
- package/src/cli/env.js +1 -1
- package/src/cli/image.js +0 -1
- package/src/cli/index.js +121 -9
- package/src/cli/lxd.js +1 -1
- package/src/cli/monitor.js +1 -1
- package/src/cli/release.js +57 -22
- package/src/cli/repository.js +11 -9
- package/src/cli/run.js +36 -9
- package/src/cli/ssh.js +198 -77
- package/src/cli/system.js +26 -13
- package/src/cli/test.js +1 -1
- package/src/cli/vultr.js +583 -0
- package/src/cli/wireguard.js +2125 -0
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +368 -0
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +33 -0
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +4 -0
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +17 -3
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +1 -1
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +40 -0
- package/src/client/services/object-layer/object-layer.management.js +4 -4
- package/src/client-builder/client-build.js +20 -14
- package/src/db/mongo/MongooseDB.js +4 -0
- package/src/index.js +25 -1
- package/src/projects/cyberia/catalog-cyberia.js +5 -0
- package/src/projects/cyberia/generate-saga.js +14 -23
- package/src/projects/cyberia/instance-data.js +21 -2
- package/src/projects/cyberia/object-layer.js +11 -21
- package/src/projects/underpost/catalog-underpost.js +4 -1
- package/src/runtime/cyberia-client/Dockerfile +1 -1
- package/src/runtime/cyberia-client/Dockerfile.dev +1 -1
- package/src/runtime/cyberia-server/Dockerfile +1 -1
- package/src/runtime/cyberia-server/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.test +1 -1
- package/src/runtime/engine-cyberia/compose.env +16 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +31 -37
- package/src/server/backup.js +1 -1
- package/src/server/conf.js +18 -108
- package/src/server/cron.js +249 -51
- package/src/server/dns.js +100 -6
- package/src/server/environment.js +98 -0
- package/src/server/forward-proxy.js +549 -0
- package/src/server/middlewares.js +56 -1
- package/src/server/process.js +0 -1
- package/src/server/selinux.js +185 -0
- package/src/server/systemd.js +205 -0
- package/src/server/underpost-compression.js +186 -0
- package/src/server/underpost-gateway.js +20 -10
- package/src/server/underpost-ingress.js +18 -2
- package/test/cyberia-instance-conf-defaults.test.js +1 -0
- package/test/selinux.test.js +71 -0
- package/test/underpost-gateway.test.js +41 -0
- package/test/underpost-ingress.test.js +52 -0
- package/test/wireguard-edge.test.js +1177 -0
package/src/cli/deploy.js
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
buildProxyRouter,
|
|
11
11
|
clusterTypeFactory,
|
|
12
12
|
Config,
|
|
13
|
-
cronDeployIdResolve,
|
|
14
13
|
deployHostsFactory,
|
|
15
14
|
deployRangePortFactory,
|
|
16
15
|
gatewayApiEnabledFactory,
|
|
@@ -24,8 +23,11 @@ import {
|
|
|
24
23
|
schedulableNodeFactory,
|
|
25
24
|
trafficFromRoutingInfoFactory,
|
|
26
25
|
} from '../server/conf.js';
|
|
26
|
+
import { cronDeployIdResolve } from '../server/cron.js';
|
|
27
27
|
import { loggerFactory } from '../server/logger.js';
|
|
28
|
+
import { HOST_VOLUME_ROOT } from '../server/environment.js';
|
|
28
29
|
import { shellExec } from '../server/process.js';
|
|
30
|
+
import { runSELinuxCommands, selinuxRestoreconCommandFactory } from '../server/selinux.js';
|
|
29
31
|
import { INTERNAL_READY_PATH, INTERNAL_HEALTH_PATH } from '../server/runtime-status.js';
|
|
30
32
|
import { staticContextRoutesFactory, statusPageRoutesFactory } from '../client-builder/client-build.js';
|
|
31
33
|
import {
|
|
@@ -152,6 +154,13 @@ const gatewayDurationFactory = (value) => {
|
|
|
152
154
|
|
|
153
155
|
const logger = loggerFactory(import.meta);
|
|
154
156
|
|
|
157
|
+
// hostPath volume trees are written under the operator's home directory, which
|
|
158
|
+
// carries a label no unprivileged container can read. Cluster bring-up registers
|
|
159
|
+
// the persistent mapping for HOST_VOLUME_ROOT; this applies it to what a deploy
|
|
160
|
+
// just wrote. A no-op where SELinux or its userspace is absent.
|
|
161
|
+
const restoreContainerContext = (path) =>
|
|
162
|
+
runSELinuxCommands([selinuxRestoreconCommandFactory(path)], { execute: shellExec });
|
|
163
|
+
|
|
155
164
|
/**
|
|
156
165
|
* @class UnderpostDeploy
|
|
157
166
|
* @description Manages the deployment of applications and services.
|
|
@@ -724,7 +733,7 @@ ${Underpost.deploy
|
|
|
724
733
|
if (!volume.claimName) continue;
|
|
725
734
|
const pvcId = `${volume.claimName}-${deployId}-${env}-${deploymentVersion}`;
|
|
726
735
|
const pvId = pvcId.replace(/^pvc-/, 'pv-');
|
|
727
|
-
const hostPath =
|
|
736
|
+
const hostPath = `${HOST_VOLUME_ROOT}/${pvId}`;
|
|
728
737
|
volumeYaml += `---\n${Underpost.deploy.persistentVolumeFactory({
|
|
729
738
|
pvcId,
|
|
730
739
|
namespace: options.namespace,
|
|
@@ -1697,13 +1706,13 @@ ${rules}`;
|
|
|
1697
1706
|
|
|
1698
1707
|
/**
|
|
1699
1708
|
* Node directory backing the static utility's volume, following the same
|
|
1700
|
-
*
|
|
1709
|
+
* `HOST_VOLUME_ROOT/<pv>` convention as every other hostPath volume.
|
|
1701
1710
|
* @param {object} [options] - Deploy/run options.
|
|
1702
1711
|
* @returns {string} Absolute host path.
|
|
1703
1712
|
* @memberof UnderpostDeploy
|
|
1704
1713
|
*/
|
|
1705
1714
|
underpostGatewayRootFactory(options = {}) {
|
|
1706
|
-
return options.underpostGatewayRoot ||
|
|
1715
|
+
return options.underpostGatewayRoot || `${HOST_VOLUME_ROOT}/${UNDERPOST_GATEWAY.volumeName}`;
|
|
1707
1716
|
},
|
|
1708
1717
|
|
|
1709
1718
|
/**
|
|
@@ -1881,6 +1890,12 @@ ${rules}`;
|
|
|
1881
1890
|
? 'project'
|
|
1882
1891
|
: null,
|
|
1883
1892
|
});
|
|
1893
|
+
// The documents were just written under the operator's home tree, whose
|
|
1894
|
+
// policy label (user_home_t) the unprivileged gateway container cannot
|
|
1895
|
+
// read — it would answer 403 for every one of them. The persistent
|
|
1896
|
+
// mapping is registered at cluster bring-up; restore it here so files
|
|
1897
|
+
// this pass created carry it too.
|
|
1898
|
+
restoreContainerContext(hostRoot);
|
|
1884
1899
|
logger.info('Static edge documents placed', {
|
|
1885
1900
|
deployId,
|
|
1886
1901
|
podName: podName || '(no running workload; placed from this checkout)',
|
|
@@ -2632,7 +2647,7 @@ EOF`);
|
|
|
2632
2647
|
const clusterContext = options.clusterContext || 'kind';
|
|
2633
2648
|
const pvcId = `${volume.claimName}-${deployId}-${env}-${version}`;
|
|
2634
2649
|
const pvId = `${volume.claimName.replace('pvc-', 'pv-')}-${deployId}-${env}-${version}`;
|
|
2635
|
-
const rootVolumeHostPath =
|
|
2650
|
+
const rootVolumeHostPath = `${HOST_VOLUME_ROOT}/${pvId}`;
|
|
2636
2651
|
if (options.gitClean && volume.volumeMountPath) {
|
|
2637
2652
|
Underpost.repo.clean({ paths: [volume.volumeMountPath] });
|
|
2638
2653
|
}
|
|
@@ -2656,6 +2671,7 @@ EOF`);
|
|
|
2656
2671
|
// Target node is the control plane / current host: write directly.
|
|
2657
2672
|
if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
|
|
2658
2673
|
fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
|
|
2674
|
+
restoreContainerContext(rootVolumeHostPath);
|
|
2659
2675
|
} else {
|
|
2660
2676
|
// Target node is remote: fs.copySync would only write the control-plane
|
|
2661
2677
|
// filesystem, leaving the real node's hostPath empty. Ship the folder to
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
MONGO_IMAGE=mongo:latest
|
|
193
193
|
VALKEY_IMAGE=valkey/valkey:latest
|
|
194
194
|
APP_IMAGE=underpost/underpost-engine
|
|
195
|
-
APP_TAG=v3.
|
|
195
|
+
APP_TAG=v3.3.0
|
|
196
196
|
PROXY_IMAGE=nginx:stable-alpine
|
|
197
197
|
PROMETHEUS_IMAGE=prom/prometheus:latest
|
|
198
198
|
GRAFANA_IMAGE=grafana/grafana:latest
|
package/src/cli/env.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @namespace UnderpostEnv
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getNpmRootPath, writeEnv } from '../server/
|
|
7
|
+
import { getNpmRootPath, writeEnv } from '../server/environment.js';
|
|
8
8
|
import fs from 'fs-extra';
|
|
9
9
|
import { loggerFactory } from '../server/logger.js';
|
|
10
10
|
import dotenv from 'dotenv';
|
package/src/cli/image.js
CHANGED
|
@@ -10,7 +10,6 @@ import nodePath from 'path';
|
|
|
10
10
|
import crypto from 'crypto';
|
|
11
11
|
import { loggerFactory } from '../server/logger.js';
|
|
12
12
|
import Underpost from '../index.js';
|
|
13
|
-
import { getNpmRootPath } from '../server/conf.js';
|
|
14
13
|
import { shellExec } from '../server/process.js';
|
|
15
14
|
import { crictlCommandFactory } from '../server/cri.js';
|
|
16
15
|
|
package/src/cli/index.js
CHANGED
|
@@ -2,7 +2,8 @@ import dotenv from 'dotenv';
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
|
-
import {
|
|
5
|
+
import { loadConf } from '../server/conf.js';
|
|
6
|
+
import { getNpmRootPath, getUnderpostRootPath } from '../server/environment.js';
|
|
6
7
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
7
8
|
|
|
8
9
|
import Underpost from '../index.js';
|
|
@@ -51,6 +52,7 @@ program
|
|
|
51
52
|
.option('--merge-zip <build-prefix>', 'Merge split ZIP parts back into a single ZIP file for the given build prefix')
|
|
52
53
|
.option('--lite-build', 'Skip full build (default is full build)')
|
|
53
54
|
.option('--icons-build', 'Build icons')
|
|
55
|
+
.option('--ssr', 'Rebuild only SSR views defined in conf.ssr.json, leaving client assets untouched')
|
|
54
56
|
.description('Builds client assets, single replicas, and/or syncs environment ports.')
|
|
55
57
|
.action(Underpost.repo.client);
|
|
56
58
|
|
|
@@ -143,7 +145,7 @@ program
|
|
|
143
145
|
'--switch-repo <url>',
|
|
144
146
|
'Switches the git remote (origin) to <url> and force-pulls the target branch, overwriting the current working tree (discards local commits and tracked changes). Accepts a full URL or "owner/repo".',
|
|
145
147
|
)
|
|
146
|
-
.option('--target-branch <branch>', 'Target branch for --switch-repo (default:
|
|
148
|
+
.option('--target-branch <branch>', 'Target branch for --switch-repo (default: remote default branch).')
|
|
147
149
|
.description('Manages commits to a GitHub repository, supporting various commit types and options.')
|
|
148
150
|
.action(Underpost.repo.commit);
|
|
149
151
|
|
|
@@ -254,6 +256,10 @@ program
|
|
|
254
256
|
.option('--ban-egress-clear', 'Clears all banned egress IP addresses.')
|
|
255
257
|
.option('--ban-both-add', 'Adds IP addresses to both banned ingress and egress lists.')
|
|
256
258
|
.option('--ban-both-remove', 'Removes IP addresses from both banned ingress and egress lists.')
|
|
259
|
+
.option('--block-all-egress', 'Blocks all outbound traffic from this host (keeps established/related connections).')
|
|
260
|
+
.option('--unblock-all-egress', 'Unblocks all outbound traffic and restores default ACCEPT policy.')
|
|
261
|
+
.option('--block-all-ingress', 'Blocks all new inbound traffic to this host (keeps established/related connections).')
|
|
262
|
+
.option('--unblock-all-ingress', 'Unblocks all inbound traffic and restores default ACCEPT policy.')
|
|
257
263
|
.option('--mac', 'Prints the MAC address of the main network interface.')
|
|
258
264
|
.description('Displays the current public machine IP addresses.')
|
|
259
265
|
.action(Underpost.dns.ipDispatcher);
|
|
@@ -592,19 +598,23 @@ program
|
|
|
592
598
|
|
|
593
599
|
program
|
|
594
600
|
.command('cron')
|
|
595
|
-
.argument(
|
|
601
|
+
.argument(
|
|
602
|
+
'[deploy-list]',
|
|
603
|
+
'A comma-separated list of deployment IDs (e.g., "default-a,default-b"). In manifest modes its first entry is the manifest owner deploy-id.',
|
|
604
|
+
)
|
|
596
605
|
.argument(
|
|
597
606
|
'[job-list]',
|
|
598
|
-
`A comma-separated list of job IDs. Options: ${Underpost.cron.getJobsIDs()}. Defaults to all available jobs.`,
|
|
607
|
+
`A comma-separated list of job IDs. Options: ${Underpost.cron.getJobsIDs()}. Defaults to all available jobs, and restricts which jobs are generated in manifest modes.`,
|
|
599
608
|
)
|
|
600
609
|
.option('--generate-k8s-cronjobs', 'Generates Kubernetes CronJob YAML manifests from cron configuration.')
|
|
601
|
-
.option('--apply', '
|
|
610
|
+
.option('--apply', 'Generates and applies K8s CronJob manifests to the cluster via kubectl (never runs jobs).')
|
|
602
611
|
.option(
|
|
603
|
-
'--setup-start
|
|
604
|
-
'Updates deploy-
|
|
612
|
+
'--setup-start',
|
|
613
|
+
'Updates deploy-list package.json start script and generates+applies its K8s CronJob manifests.',
|
|
605
614
|
)
|
|
606
615
|
.option('--namespace <namespace>', 'Kubernetes namespace for the CronJob resources (default: "default").')
|
|
607
616
|
.option('--image <image>', 'Custom container image for the CronJob pods.')
|
|
617
|
+
.option('--node-name <node-name>', 'Pins the CronJob pods to this node via a kubernetes.io/hostname nodeSelector.')
|
|
608
618
|
.option('--git', 'Pass --git flag to cron job execution.')
|
|
609
619
|
.option('--cmd <cmd>', 'Optional pre-script commands to run before cron execution.')
|
|
610
620
|
.option('--dev', 'Use local ./ base path instead of global underpost installation.')
|
|
@@ -614,7 +624,7 @@ program
|
|
|
614
624
|
.option('--dry-run', 'Preview cron jobs without executing them.')
|
|
615
625
|
.option(
|
|
616
626
|
'--create-job-now',
|
|
617
|
-
'
|
|
627
|
+
'Creates a Job from each CronJob on the cluster now (implies manifest mode; combine with --apply to publish first).',
|
|
618
628
|
)
|
|
619
629
|
.description('Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manifests.')
|
|
620
630
|
.action(Underpost.cron.callback);
|
|
@@ -696,6 +706,108 @@ program
|
|
|
696
706
|
.description('Manages SSH credentials and sessions for remote access to cluster nodes or services.')
|
|
697
707
|
.action(Underpost.ssh.callback);
|
|
698
708
|
|
|
709
|
+
// `underpost wireguard` and `underpost haproxy` are two entrypoints onto one
|
|
710
|
+
// subsystem: the L3 transport and the gateway in front of it are configured from
|
|
711
|
+
// the same deploy state, so they share a single option set and a single action
|
|
712
|
+
// rather than drifting into two half-overlapping command surfaces.
|
|
713
|
+
const edgeCommandFactory = (name, description) =>
|
|
714
|
+
program
|
|
715
|
+
.command(name)
|
|
716
|
+
.option(
|
|
717
|
+
'--deploy-id <deploy-id>',
|
|
718
|
+
'Deploy IDs whose conf.server.json/conf.instances.json define the routes. ' +
|
|
719
|
+
'Accepts one id or a comma-separated list; defaults to "dd", every deploy in dd.router, ' +
|
|
720
|
+
'because the edge holds one pair of map files for the whole cluster.',
|
|
721
|
+
)
|
|
722
|
+
.option('--interface <name>', 'WireGuard interface name (default: "wg0").')
|
|
723
|
+
.option('--wireguard-install', 'Installs the wireguard-tools, haproxy and iptables host packages.')
|
|
724
|
+
.option('--wireguard-setup', 'Generates keys, builds the interface config, and applies local network rules.')
|
|
725
|
+
.option('--server', 'Configures this node as the hub endpoint accepting inbound tunnel traffic.')
|
|
726
|
+
.option('--client', 'Configures this node as a spoke endpoint maintaining an outbound tunnel.')
|
|
727
|
+
.option('--port <port>', 'WireGuard UDP listening port (default: 51820).')
|
|
728
|
+
.option(
|
|
729
|
+
'--cidr <cidr>',
|
|
730
|
+
'Hub interface address with prefix when used with --server (e.g. "10.0.0.1/24"); ' +
|
|
731
|
+
'the overlay subnet a spoke routes back through the hub when used with --client (default: "10.0.0.0/24").',
|
|
732
|
+
)
|
|
733
|
+
.option('--peer-ip <ip>', 'Tunnel address of the target spoke. Required with --client and --peer-add.')
|
|
734
|
+
.option('--endpoint <host:port>', 'Hub host and port a spoke dials. Required with --client.')
|
|
735
|
+
.option('--public-key <key>', 'Hub public key with --client; spoke public key with --peer-add.')
|
|
736
|
+
.option('--peer-add <peer-id>', 'Registers a spoke and applies it to the running hub without a restart.')
|
|
737
|
+
.option('--peer-remove <peer-id>', 'Removes a spoke from the registry and from the running hub.')
|
|
738
|
+
.option('--allowed-ips <cidrs>', 'Comma-separated CIDRs routed to the spoke (e.g. "10.0.0.2/32,192.168.10.0/24").')
|
|
739
|
+
.option('--hosts <hosts>', 'Comma-separated hostnames bound to the spoke, overriding instance resolution.')
|
|
740
|
+
.option('--instances <instances>', 'Comma-separated conf.instances.json ids bound to the spoke.')
|
|
741
|
+
.option('--default', 'Marks the spoke as the fallback for hostnames that match no other binding.')
|
|
742
|
+
.option('--haproxy-setup', 'Installs HAProxy, publishes the current routes, and enables the daemon.')
|
|
743
|
+
.option('--haproxy-sync', 'Recompiles the SNI/Host maps from deploy config and hot-reloads HAProxy.')
|
|
744
|
+
.option(
|
|
745
|
+
'--status',
|
|
746
|
+
'Prints the whole edge context without changing anything: role, interface, tunnel address, ' +
|
|
747
|
+
'public key, daemon states, peers with their bindings and link health, and the resolved routing.',
|
|
748
|
+
)
|
|
749
|
+
.option(
|
|
750
|
+
'--build-conf',
|
|
751
|
+
'Writes only engine-private/deploy/conf.wireguard.json and touches no host state. ' +
|
|
752
|
+
'Combine with --wireguard-setup / --peer-add / --peer-remove to author the topology off-box; ' +
|
|
753
|
+
'alone it normalizes and validates the existing registry.',
|
|
754
|
+
)
|
|
755
|
+
.option(
|
|
756
|
+
'--forward-proxy-server',
|
|
757
|
+
'Ensures the hub HTTP/CONNECT forward proxy runs as the underpost-forward-proxy systemd service, ' +
|
|
758
|
+
'bound to the tunnel address only (default port 1080), and returns. Authenticates every request with ' +
|
|
759
|
+
'FORWARD_PROXY_API_KEY, so spokes can reach the internet through the VPS public address. Idempotent: ' +
|
|
760
|
+
're-running converges on the one service and restarts it only when the unit actually changed.',
|
|
761
|
+
)
|
|
762
|
+
.option(
|
|
763
|
+
'--forward-proxy-server-host <host>',
|
|
764
|
+
'Address the forward proxy binds, overriding the hub tunnel address from the registry.',
|
|
765
|
+
)
|
|
766
|
+
.option('--forward-proxy-server-port <port>', 'Port the forward proxy binds (default: 1080).')
|
|
767
|
+
.option(
|
|
768
|
+
'--ssh-forward-port <port>',
|
|
769
|
+
'Publishes the default spoke SSH port on this public TCP port of the hub, so CI with no fixed ' +
|
|
770
|
+
'address can reach the cluster node (e.g. 2222). "0" closes it. Stored in the registry.',
|
|
771
|
+
)
|
|
772
|
+
.option('--wireguard-start', 'Enables and starts wg-quick@<interface> and the QUIC forward.')
|
|
773
|
+
.option('--wireguard-stop', 'Tears down the interface and removes its transient packet rules.')
|
|
774
|
+
.option('--wireguard-reset', 'Removes generated configs and packet rules, keeping the key pair and registry.')
|
|
775
|
+
.option('--wireguard-reinstall', 'Full purge, package reinstall and re-key; every spoke must re-register.')
|
|
776
|
+
.option('--dry-run', 'Prints the files and commands the run would apply, without touching the host.')
|
|
777
|
+
.description(description)
|
|
778
|
+
.action(Underpost.wireguard.callback);
|
|
779
|
+
|
|
780
|
+
edgeCommandFactory(
|
|
781
|
+
'wireguard',
|
|
782
|
+
'Manages the WireGuard L3 hub-and-spoke transport and the HAProxy edge gateway in front of it.',
|
|
783
|
+
);
|
|
784
|
+
edgeCommandFactory(
|
|
785
|
+
'haproxy',
|
|
786
|
+
'Manages the HAProxy edge gateway over the WireGuard transport (same subsystem as `underpost wireguard`).',
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
program
|
|
790
|
+
.command('vultr')
|
|
791
|
+
.argument('[deploy-list]', 'A comma-separated list of deployment IDs, logged for attribution.')
|
|
792
|
+
.option('--instance-id <instance-id>', 'Vultr instance id to meter (default: VULTR_INSTANCE_ID).')
|
|
793
|
+
.option('--api-key <api-key>', 'Vultr API key (default: VULTR_API_KEY). Prefer the environment over this flag.')
|
|
794
|
+
.option(
|
|
795
|
+
'--threshold <ratio>',
|
|
796
|
+
'Fraction of the plan quota that triggers the egress block; "0.80" and "80" are both accepted (default: 0.80).',
|
|
797
|
+
)
|
|
798
|
+
.option('--metric <metric>', '"total" (incoming + outgoing, default) or "outgoing" for egress alone.')
|
|
799
|
+
.option('--month <yyyy-mm>', 'Billing month to sum (default: the current UTC month).')
|
|
800
|
+
.option('--all-dates', 'Sum every daily bucket the API returns instead of scoping to one month.')
|
|
801
|
+
.option('--host <ip>', 'Edge VPS to block (default: VULTR_VPS_IP, then DEFAULT_SSH_HOST).')
|
|
802
|
+
.option('--user <user>', 'SSH user on the edge VPS (default: VULTR_SSH_USER, then DEFAULT_SSH_USER, then "root").')
|
|
803
|
+
.option('--key-path <path>', 'SSH private key (default: VULTR_SSH_KEY_PATH, then DEFAULT_SSH_KEY_PATH).')
|
|
804
|
+
.option('--port <port>', 'SSH port on the edge VPS (default: VULTR_SSH_PORT, then DEFAULT_SSH_PORT, then 22).')
|
|
805
|
+
.option('--force', 'Re-apply the egress block even if it was already applied for this cycle.')
|
|
806
|
+
.option('--auto-unblock', 'Restore egress automatically once consumption falls back under the threshold.')
|
|
807
|
+
.option('--dry-run', 'Reports the consumption and the action it would take, without touching the edge VPS.')
|
|
808
|
+
.description('Meters the edge VPS bandwidth against its Vultr plan quota and blocks egress before overage accrues.')
|
|
809
|
+
.action(Underpost.vultr.callback);
|
|
810
|
+
|
|
699
811
|
program
|
|
700
812
|
.command('run')
|
|
701
813
|
.argument('<runner-id>', `The runner ID to run. Options: ${Underpost.run.RUNNERS}.`)
|
|
@@ -769,7 +881,7 @@ program
|
|
|
769
881
|
.option('--cmd-cron-jobs <cmd-cron-jobs>', 'Pre-script commands to run before cron job execution.')
|
|
770
882
|
.option(
|
|
771
883
|
'--deploy-id-cron-jobs <deploy-id-cron-jobs>',
|
|
772
|
-
'
|
|
884
|
+
'Cron deploy-id to set up during sync; defaults to dd.cron, "none" skips cron setup entirely.',
|
|
773
885
|
)
|
|
774
886
|
.option('--timezone <timezone>', 'Sets the timezone for the runner execution.')
|
|
775
887
|
.option('--kubeadm', 'Sets the kubeadm cluster context for the runner execution.')
|
package/src/cli/lxd.js
CHANGED
package/src/cli/monitor.js
CHANGED
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
loadReplicas,
|
|
9
9
|
pathPortAssignmentFactory,
|
|
10
10
|
loadConfServerJson,
|
|
11
|
-
loadCronDeployEnv,
|
|
12
11
|
etcHostFactory,
|
|
13
12
|
deployRangePortFactory,
|
|
14
13
|
} from '../server/conf.js';
|
|
14
|
+
import { loadCronDeployEnv } from '../server/cron.js';
|
|
15
15
|
import { loggerFactory } from '../server/logger.js';
|
|
16
16
|
import { timer } from '../client/components/core/CommonJs.js';
|
|
17
17
|
import {
|
package/src/cli/release.js
CHANGED
|
@@ -56,6 +56,10 @@ const buildVersionBumpTargets = () => [
|
|
|
56
56
|
file: 'src/index.js',
|
|
57
57
|
patterns: /(static version = ['"]v)\d+\.\d+\.\d+(?=['"])/g,
|
|
58
58
|
},
|
|
59
|
+
{
|
|
60
|
+
file: 'src/cli/run.js',
|
|
61
|
+
patterns: /(const version = ['"]v)\d+\.\d+\.\d+(?=['"])/g,
|
|
62
|
+
},
|
|
59
63
|
|
|
60
64
|
// ── README + CLI-HELP fallbacks. CLI-HELP is regenerated by `deploy cli-docs`, but bump
|
|
61
65
|
// it too so the file is consistent if the regeneration step is skipped. ──
|
|
@@ -107,6 +111,14 @@ const buildVersionBumpTargets = () => [
|
|
|
107
111
|
recursive: true,
|
|
108
112
|
},
|
|
109
113
|
|
|
114
|
+
// ── Deployment runner scripts carry image defaults passed to deploy/sync commands. ──
|
|
115
|
+
{
|
|
116
|
+
dir: 'deploy',
|
|
117
|
+
match: /\.sh$/,
|
|
118
|
+
patterns: /(underpost\/[a-z0-9-]+:v)\d+\.\d+\.\d+/g,
|
|
119
|
+
recursive: true,
|
|
120
|
+
},
|
|
121
|
+
|
|
110
122
|
// ── GitHub Actions workflows. Single sweep across docker-image.*.ci.yml, engine-*.cd.yml,
|
|
111
123
|
// and the root docker-image.ci.yml — replaces previous three separate loops. ──
|
|
112
124
|
{
|
|
@@ -261,6 +273,19 @@ const bumpAuxiliaryFiles = (oldVersion, newVersion, { dryRun = false } = {}) =>
|
|
|
261
273
|
return report;
|
|
262
274
|
};
|
|
263
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Returns whether a manifest's canonical top-level version would change. Used by dry-runs
|
|
278
|
+
* because bumpp has no non-mutating API option.
|
|
279
|
+
*/
|
|
280
|
+
const wouldBumpManifestVersion = (filePath, newVersion) => {
|
|
281
|
+
try {
|
|
282
|
+
const manifest = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
283
|
+
return typeof manifest.version === 'string' && manifest.version !== newVersion;
|
|
284
|
+
} catch {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
264
289
|
/**
|
|
265
290
|
* Prints a per-file change summary table.
|
|
266
291
|
*/
|
|
@@ -379,8 +404,8 @@ class UnderpostRelease {
|
|
|
379
404
|
* 1. Loads production env and pulls latest code; kills dev servers on ports 4001-4003.
|
|
380
405
|
* 2. Builds and smoke-tests the pwa-microservices-template (aborts on error).
|
|
381
406
|
* 3. Canonical version files: delegates to `bumpp` (driven by `bump.config.js`). Bumps
|
|
382
|
-
* package.json, package-lock.json (root + packages['']),
|
|
383
|
-
* engine-private/conf/**\/package.json.
|
|
407
|
+
* package.json, package-lock.json (root + packages['']), Hardhat's package metadata,
|
|
408
|
+
* and every engine-private/conf/**\/package.json.
|
|
384
409
|
* 4. Auxiliary files: anchored-regex walker over VERSION_BUMP_TARGETS — covers
|
|
385
410
|
* src/index.js, README, cyberia-docs, nexodev docs, manifests (deployment + cronjobs),
|
|
386
411
|
* .github/workflows (image tags, type=raw, UNDERPOST_VERSION build-args), and
|
|
@@ -420,26 +445,36 @@ class UnderpostRelease {
|
|
|
420
445
|
if (!templateOk) return;
|
|
421
446
|
}
|
|
422
447
|
|
|
423
|
-
// ── Canonical version files:
|
|
424
|
-
//
|
|
425
|
-
//
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
448
|
+
// ── Canonical version files: bumpp owns lockfile semantics (root version +
|
|
449
|
+
// packages[''].version). Its API has no non-mutating dry-run, so previews inspect
|
|
450
|
+
// manifest versions directly rather than invoking it. ──
|
|
451
|
+
const canonicalVersionFiles = [
|
|
452
|
+
'package.json',
|
|
453
|
+
'package-lock.json',
|
|
454
|
+
'hardhat/package.json',
|
|
455
|
+
'hardhat/package-lock.json',
|
|
456
|
+
...walkDir('engine-private/conf', /^package\.json$/, true),
|
|
457
|
+
];
|
|
458
|
+
if (dryRun) {
|
|
459
|
+
const pendingCanonicalFiles = canonicalVersionFiles.filter((file) =>
|
|
460
|
+
wouldBumpManifestVersion(file, newVersion),
|
|
461
|
+
);
|
|
462
|
+
logger.info(`bumpp would update ${pendingCanonicalFiles.length} canonical file(s).`);
|
|
463
|
+
for (const file of pendingCanonicalFiles) console.log(` ${file}`);
|
|
464
|
+
} else {
|
|
465
|
+
const { versionBump } = await import('bumpp');
|
|
466
|
+
const bumppResult = await versionBump({
|
|
467
|
+
release: newVersion,
|
|
468
|
+
files: canonicalVersionFiles,
|
|
469
|
+
commit: false,
|
|
470
|
+
tag: false,
|
|
471
|
+
push: false,
|
|
472
|
+
confirm: false,
|
|
473
|
+
recursive: false,
|
|
474
|
+
ignoreScripts: true,
|
|
475
|
+
});
|
|
476
|
+
logger.info(`bumpp updated ${bumppResult?.updatedFiles?.length ?? 0} canonical file(s).`);
|
|
477
|
+
}
|
|
443
478
|
|
|
444
479
|
// ── Auxiliary files: anchored-regex walker over VERSION_BUMP_TARGETS. ──
|
|
445
480
|
const report = bumpAuxiliaryFiles(version, newVersion, { dryRun });
|
package/src/cli/repository.js
CHANGED
|
@@ -11,7 +11,6 @@ import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
13
|
import {
|
|
14
|
-
getNpmRootPath,
|
|
15
14
|
Config,
|
|
16
15
|
loadConf,
|
|
17
16
|
readConfJson,
|
|
@@ -20,9 +19,9 @@ import {
|
|
|
20
19
|
loadConfServerJson,
|
|
21
20
|
getDataDeploy,
|
|
22
21
|
buildReplicaId,
|
|
23
|
-
writeEnv,
|
|
24
22
|
readConfInstances,
|
|
25
23
|
} from '../server/conf.js';
|
|
24
|
+
import { getNpmRootPath, writeEnv } from '../server/environment.js';
|
|
26
25
|
import { buildClient, unzipClientBuild, mergeClientBuildZip } from '../client-builder/client-build.js';
|
|
27
26
|
import { DefaultConf } from '../../conf.js';
|
|
28
27
|
import Underpost from '../index.js';
|
|
@@ -109,7 +108,7 @@ class UnderpostRepository {
|
|
|
109
108
|
* @param {boolean} [options.changelogNoHash=false] - If true, omits commit hashes from the changelog entries.
|
|
110
109
|
* @param {boolean} [options.remoteUrl=false] - If true, prints the current git remote URL (origin) in plain text and returns.
|
|
111
110
|
* @param {string} [options.switchRepo=''] - If set, switches the remote `origin` to this URL and force-pulls the target branch, overwriting the current working tree.
|
|
112
|
-
* @param {string} [options.targetBranch=''] - Target branch for `switchRepo` (defaults to
|
|
111
|
+
* @param {string} [options.targetBranch=''] - Target branch for `switchRepo` (defaults to the remote's default branch).
|
|
113
112
|
* @memberof UnderpostRepository
|
|
114
113
|
*/
|
|
115
114
|
commit(
|
|
@@ -181,7 +180,7 @@ class UnderpostRepository {
|
|
|
181
180
|
Underpost.repo.switchRemote({
|
|
182
181
|
path: repoPath,
|
|
183
182
|
url: options.switchRepo,
|
|
184
|
-
branch: options.targetBranch
|
|
183
|
+
branch: options.targetBranch,
|
|
185
184
|
});
|
|
186
185
|
return;
|
|
187
186
|
}
|
|
@@ -906,6 +905,7 @@ class UnderpostRepository {
|
|
|
906
905
|
split: options.split || '',
|
|
907
906
|
fullBuild: options.liteBuild ? false : true,
|
|
908
907
|
iconsBuild: options.iconsBuild || false,
|
|
908
|
+
ssrOnly: options.ssr || false,
|
|
909
909
|
});
|
|
910
910
|
for (const replicaDeployId of deployIdSingleReplicas) {
|
|
911
911
|
if (!fs.existsSync(`./engine-private/replica/${replicaDeployId}`)) {
|
|
@@ -917,6 +917,7 @@ class UnderpostRepository {
|
|
|
917
917
|
split: options.split || '',
|
|
918
918
|
liteBuild: options.liteBuild || false,
|
|
919
919
|
iconsBuild: options.iconsBuild || false,
|
|
920
|
+
ssr: options.ssr || false,
|
|
920
921
|
});
|
|
921
922
|
}
|
|
922
923
|
|
|
@@ -1428,14 +1429,15 @@ Prevent build private config repo.`,
|
|
|
1428
1429
|
* @param {object} opts
|
|
1429
1430
|
* @param {string} opts.url - New remote URL (full URL or "owner/repo" short form).
|
|
1430
1431
|
* @param {string} [opts.path='.'] - Path to the git repository.
|
|
1431
|
-
* @param {string} [opts.branch
|
|
1432
|
+
* @param {string} [opts.branch] - Target branch to overwrite the current tree with. Defaults to the remote's default branch.
|
|
1432
1433
|
* @param {string} [opts.remote='origin'] - Remote name to set and fetch from.
|
|
1433
1434
|
* @returns {void}
|
|
1434
1435
|
* @memberof UnderpostRepository
|
|
1435
1436
|
*/
|
|
1436
|
-
switchRemote({ url, path: repoPath = '.', branch = '
|
|
1437
|
+
switchRemote({ url, path: repoPath = '.', branch = '', remote = 'origin' }) {
|
|
1437
1438
|
if (!url) throw new Error('switchRemote requires a target remote url');
|
|
1438
1439
|
if (!fs.existsSync(`${repoPath}/.git`)) throw new Error(`switchRemote: not a git repository: ${repoPath}`);
|
|
1440
|
+
const targetBranch = branch || Underpost.repo.getDefaultBranch(url);
|
|
1439
1441
|
// Token-free URL for the stored remote; auth-injected URL only for the fetch.
|
|
1440
1442
|
let normalized = url;
|
|
1441
1443
|
if (!url.startsWith('http://') && !url.startsWith('https://') && !url.startsWith('git@')) {
|
|
@@ -1445,12 +1447,12 @@ Prevent build private config repo.`,
|
|
|
1445
1447
|
const current = Underpost.repo.getRemoteUrl({ path: repoPath, remote });
|
|
1446
1448
|
if (!current) shellExec(`cd "${repoPath}" && git remote add ${remote} "${normalized}"`);
|
|
1447
1449
|
else shellExec(`cd "${repoPath}" && git remote set-url ${remote} "${normalized}"`);
|
|
1448
|
-
logger.info('switchRemote', { path: repoPath, remote, branch, url: normalized });
|
|
1449
|
-
shellExec(`cd "${repoPath}" && GIT_TERMINAL_PROMPT=0 git fetch --force "${authUrl}" ${
|
|
1450
|
+
logger.info('switchRemote', { path: repoPath, remote, branch: targetBranch, url: normalized });
|
|
1451
|
+
shellExec(`cd "${repoPath}" && GIT_TERMINAL_PROMPT=0 git fetch --force "${authUrl}" ${targetBranch}`);
|
|
1450
1452
|
// reset --hard first clears the worktree so the checkout cannot be blocked
|
|
1451
1453
|
// by conflicting local changes; -B points the target branch at the fetched tip.
|
|
1452
1454
|
shellExec(`cd "${repoPath}" && git reset --hard FETCH_HEAD`);
|
|
1453
|
-
shellExec(`cd "${repoPath}" && git checkout -B ${
|
|
1455
|
+
shellExec(`cd "${repoPath}" && git checkout -B ${targetBranch} FETCH_HEAD`);
|
|
1454
1456
|
},
|
|
1455
1457
|
|
|
1456
1458
|
/**
|
package/src/cli/run.js
CHANGED
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
* @namespace UnderpostRun
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { daemonProcess,
|
|
7
|
+
import { daemonProcess, pbcopy, shellCd, shellExec } from '../server/process.js';
|
|
8
8
|
import {
|
|
9
9
|
awaitDeployMonitor,
|
|
10
10
|
buildKindPorts,
|
|
11
11
|
clusterContextFactory,
|
|
12
12
|
clusterTypeFactory,
|
|
13
|
-
cronDeployIdResolve,
|
|
14
13
|
dispatchBuildInstanceEnv,
|
|
15
14
|
deployHostsFactory,
|
|
16
15
|
etcHostFactory,
|
|
@@ -21,7 +20,6 @@ import {
|
|
|
21
20
|
exposeTcpPortsFactory,
|
|
22
21
|
gatewayApiEnabledFactory,
|
|
23
22
|
generateSecurePassword,
|
|
24
|
-
getNpmRootPath,
|
|
25
23
|
instanceHttpRouteRulesFactory,
|
|
26
24
|
instanceInterceptStatusesFactory,
|
|
27
25
|
instancePortFactory,
|
|
@@ -36,7 +34,6 @@ import {
|
|
|
36
34
|
resolveEnvScoped,
|
|
37
35
|
selectConfInstances,
|
|
38
36
|
waitForPort,
|
|
39
|
-
writeEnv,
|
|
40
37
|
clusterInstancesFactory,
|
|
41
38
|
deployTrafficEntriesFactory,
|
|
42
39
|
curlStatusChainFactory,
|
|
@@ -49,6 +46,8 @@ import {
|
|
|
49
46
|
stopPlanFactory,
|
|
50
47
|
trafficFromRoutingInfoFactory,
|
|
51
48
|
} from '../server/conf.js';
|
|
49
|
+
import { cronDeployIdResolve } from '../server/cron.js';
|
|
50
|
+
import { getNpmRootPath, writeEnv } from '../server/environment.js';
|
|
52
51
|
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
53
52
|
|
|
54
53
|
import fs from 'fs-extra';
|
|
@@ -127,7 +126,7 @@ const logger = loggerFactory(import.meta);
|
|
|
127
126
|
* @property {string} confServerPath - The configuration server path.
|
|
128
127
|
* @property {string} underpostRoot - The root path of the Underpost installation.
|
|
129
128
|
* @property {string} cmdCronJobs - Pre-script commands to run before cron job execution.
|
|
130
|
-
* @property {string} deployIdCronJobs -
|
|
129
|
+
* @property {string} deployIdCronJobs - Cron deploy-id passed to `cron --setup-start`; unset resolves dd.cron, `none` skips cron setup.
|
|
131
130
|
* @property {string} timezone - The timezone to set.
|
|
132
131
|
* @property {boolean} kubeadm - Whether to run in kubeadm mode.
|
|
133
132
|
* @property {boolean} kind - Whether to run in kind mode.
|
|
@@ -1172,8 +1171,16 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1172
1171
|
if (!validVersion) throw new Error('Version mismatch');
|
|
1173
1172
|
}
|
|
1174
1173
|
if (options.timezone !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
1175
|
-
if (options.deployIdCronJobs !== 'none')
|
|
1176
|
-
|
|
1174
|
+
if (options.deployIdCronJobs !== 'none') {
|
|
1175
|
+
// --deploy-id-cron-jobs overrides the cron deploy-id; unset falls back to
|
|
1176
|
+
// dd.cron, the same source `cron --setup-start` resolves against on its own.
|
|
1177
|
+
const cronDeployId = options.deployIdCronJobs || cronDeployIdResolve() || '';
|
|
1178
|
+
if (cronDeployId && !/^[a-zA-Z0-9._,-]+$/.test(cronDeployId))
|
|
1179
|
+
throw new Error(`Invalid cron deploy-id: ${cronDeployId}`);
|
|
1180
|
+
shellExec(
|
|
1181
|
+
`node bin cron${cronDeployId ? ` ${cronDeployId}` : ''}${baseClusterCommand}${clusterFlag} --setup-start --git --apply`,
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1177
1184
|
}
|
|
1178
1185
|
|
|
1179
1186
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
@@ -1220,7 +1227,7 @@ echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com
|
|
|
1220
1227
|
// runner. Build the host-side SSR documents before generating routes unless
|
|
1221
1228
|
// the caller explicitly selected a pre-built bundle workflow.
|
|
1222
1229
|
if (isDeployRunnerContext(path, options) && !options.skipFullBuild)
|
|
1223
|
-
shellExec(`${baseCommand} client ${deployId} ${env}`);
|
|
1230
|
+
shellExec(`${baseCommand} client ${deployId} ${env} --ssr`);
|
|
1224
1231
|
|
|
1225
1232
|
shellExec(
|
|
1226
1233
|
`${baseCommand} deploy${clusterFlag} --build-manifest --sync --info-router --replicas ${replicas} --node ${node}${
|
|
@@ -3090,7 +3097,7 @@ EOF`);
|
|
|
3090
3097
|
const hostListenResult = etcHostFactory(hosts);
|
|
3091
3098
|
logger.info(hostListenResult.renderHosts);
|
|
3092
3099
|
}
|
|
3093
|
-
const version = 'v3.
|
|
3100
|
+
const version = 'v3.3.0';
|
|
3094
3101
|
const instanceOptionsFactory = (deployId, instanceId) => ({
|
|
3095
3102
|
...options,
|
|
3096
3103
|
...clusterContextFactory(clusterType),
|
|
@@ -4906,6 +4913,26 @@ EOF`;
|
|
|
4906
4913
|
}
|
|
4907
4914
|
},
|
|
4908
4915
|
|
|
4916
|
+
/**
|
|
4917
|
+
* @method kubeadm-wireguard
|
|
4918
|
+
* @description
|
|
4919
|
+
* Configures Calico to keep using the Kubernetes NodeInternalIP after WireGuard
|
|
4920
|
+
* is added to the node. This prevents the WireGuard interface (for example
|
|
4921
|
+
* 10.0.0.2) from being selected as the Calico/BGP node address.
|
|
4922
|
+
*
|
|
4923
|
+
* @param {string} path - Unused.
|
|
4924
|
+
* @param {UnderpostRunDefaultOptions} options - The default underpost runner options.
|
|
4925
|
+
* @memberof UnderpostRun
|
|
4926
|
+
*/
|
|
4927
|
+
'kubeadm-wireguard': (path, options = DEFAULT_OPTION) => {
|
|
4928
|
+
shellExec(`kubectl patch installation.operator.tigera.io default --type='json' \
|
|
4929
|
+
-p='[
|
|
4930
|
+
{"op":"replace","path":"/spec/calicoNetwork/nodeAddressAutodetectionV4","value":{"kubernetes":"NodeInternalIP"}}
|
|
4931
|
+
]'`);
|
|
4932
|
+
|
|
4933
|
+
shellExec(`kubectl rollout restart daemonset/calico-node -n calico-system`);
|
|
4934
|
+
},
|
|
4935
|
+
|
|
4909
4936
|
/**
|
|
4910
4937
|
* @method build-cluster-deployment-manifests
|
|
4911
4938
|
* @description Builds deployment manifests for both production and development environments using `node bin deploy --build-manifest`, syncing them, and setting replicas to 1 for the `dd` deployment.
|