@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
|
@@ -525,6 +525,7 @@ const defaultSitemapXsl = `<?xml version="1.0" encoding="UTF-8"?>
|
|
|
525
525
|
* @param {string|number} options.split - Optional zip split size in MB.
|
|
526
526
|
* @param {boolean} options.fullBuild - Whether to perform a full build.
|
|
527
527
|
* @param {boolean} options.iconsBuild - Whether to build icons.
|
|
528
|
+
* @param {boolean} options.ssrOnly - Whether to rebuild only views defined in `conf.ssr.json`.
|
|
528
529
|
* @returns {Promise<void>} - Promise that resolves when the build is complete.
|
|
529
530
|
* @throws {Error} - If the build fails.
|
|
530
531
|
* @memberof clientBuild
|
|
@@ -548,6 +549,7 @@ const buildClient = async (
|
|
|
548
549
|
const packageData = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
549
550
|
const acmeChallengePath = `/.well-known/acme-challenge`;
|
|
550
551
|
const publicPath = `./public`;
|
|
552
|
+
const ssrOnly = options.ssrOnly === true;
|
|
551
553
|
|
|
552
554
|
/**
|
|
553
555
|
* @async
|
|
@@ -691,11 +693,11 @@ const buildClient = async (
|
|
|
691
693
|
? `${directory}${acmeChallengePath}`
|
|
692
694
|
: `${publicPath}/${host}${acmeChallengePath}`;
|
|
693
695
|
|
|
694
|
-
if (!enableLiveRebuild) buildAcmeChallengePath(acmeChallengeFullPath);
|
|
696
|
+
if (!enableLiveRebuild && !ssrOnly) buildAcmeChallengePath(acmeChallengeFullPath);
|
|
695
697
|
|
|
696
698
|
if (redirect || disabledRebuild) continue;
|
|
697
699
|
|
|
698
|
-
if (fullBuildEnabled)
|
|
700
|
+
if (fullBuildEnabled && !ssrOnly)
|
|
699
701
|
await fullBuild({
|
|
700
702
|
path,
|
|
701
703
|
logger,
|
|
@@ -710,7 +712,7 @@ const buildClient = async (
|
|
|
710
712
|
publicCopyNonExistingFiles,
|
|
711
713
|
});
|
|
712
714
|
|
|
713
|
-
if (components)
|
|
715
|
+
if (!ssrOnly && components)
|
|
714
716
|
for (const module of Object.keys(components)) {
|
|
715
717
|
if (!fs.existsSync(`${rootClientPath}/components/${module}`))
|
|
716
718
|
fs.mkdirSync(`${rootClientPath}/components/${module}`, { recursive: true });
|
|
@@ -733,7 +735,7 @@ const buildClient = async (
|
|
|
733
735
|
}
|
|
734
736
|
}
|
|
735
737
|
|
|
736
|
-
if (services) {
|
|
738
|
+
if (!ssrOnly && services) {
|
|
737
739
|
for (const module of services) {
|
|
738
740
|
if (!fs.existsSync(`${rootClientPath}/services/${module}`))
|
|
739
741
|
fs.mkdirSync(`${rootClientPath}/services/${module}`, { recursive: true });
|
|
@@ -796,7 +798,9 @@ const buildClient = async (
|
|
|
796
798
|
const swSrcPath = `./src/client/sw/core.sw.js`;
|
|
797
799
|
const swPublicPath = `${rootClientPath}/sw.js`;
|
|
798
800
|
const swShouldRebuild =
|
|
799
|
-
|
|
801
|
+
!ssrOnly &&
|
|
802
|
+
views &&
|
|
803
|
+
!(enableLiveRebuild && !options.liveClientBuildPaths.find((p) => p.srcBuildPath === swSrcPath));
|
|
800
804
|
// Transformed SW JS is held in memory; it gets prepended with renderPayload
|
|
801
805
|
// and written once below, after PRE_CACHED_RESOURCES are known.
|
|
802
806
|
let swTransformedJs = '';
|
|
@@ -810,13 +814,15 @@ const buildClient = async (
|
|
|
810
814
|
});
|
|
811
815
|
}
|
|
812
816
|
|
|
813
|
-
if (views) {
|
|
814
|
-
if (
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
817
|
+
if (!ssrOnly && views) {
|
|
818
|
+
if (
|
|
819
|
+
!(
|
|
820
|
+
enableLiveRebuild &&
|
|
821
|
+
!options.liveClientBuildPaths.find(
|
|
822
|
+
(p) => p.srcBuildPath.startsWith(`./src/client/ssr`) || p.srcBuildPath.slice(-9) === '.index.js',
|
|
823
|
+
)
|
|
818
824
|
)
|
|
819
|
-
)
|
|
825
|
+
)
|
|
820
826
|
for (const view of views) {
|
|
821
827
|
const buildPath = `${
|
|
822
828
|
rootClientPath[rootClientPath.length - 1] === '/' ? rootClientPath.slice(0, -1) : rootClientPath
|
|
@@ -983,7 +989,7 @@ const buildClient = async (
|
|
|
983
989
|
);
|
|
984
990
|
}
|
|
985
991
|
}
|
|
986
|
-
if (!enableLiveRebuild && siteMapLinks.length > 0) {
|
|
992
|
+
if (!ssrOnly && !enableLiveRebuild && siteMapLinks.length > 0) {
|
|
987
993
|
const hasSitemapTemplate = fs.existsSync(`${rootClientPath}/sitemap`);
|
|
988
994
|
const sitemapBaseUrl = `https://${host}${path === '/' ? '' : path}`;
|
|
989
995
|
// Create a stream to write to — omit xslUrl so we can inject a relative href below
|
|
@@ -1020,7 +1026,7 @@ Sitemap: ${sitemapBaseUrl}/sitemap.xml`,
|
|
|
1020
1026
|
);
|
|
1021
1027
|
}
|
|
1022
1028
|
|
|
1023
|
-
if (fullBuildEnabled && docs) {
|
|
1029
|
+
if (!ssrOnly && fullBuildEnabled && docs) {
|
|
1024
1030
|
await buildDocs({
|
|
1025
1031
|
host,
|
|
1026
1032
|
path,
|
|
@@ -1128,7 +1134,7 @@ ${swTransformedJs}`,
|
|
|
1128
1134
|
);
|
|
1129
1135
|
}
|
|
1130
1136
|
}
|
|
1131
|
-
if (!enableLiveRebuild && options.buildZip) {
|
|
1137
|
+
if (!ssrOnly && !enableLiveRebuild && options.buildZip) {
|
|
1132
1138
|
logger.warn('build zip', rootClientPath);
|
|
1133
1139
|
|
|
1134
1140
|
if (!fs.existsSync('./build')) fs.mkdirSync('./build');
|
|
@@ -186,6 +186,10 @@ class MongooseDBService {
|
|
|
186
186
|
const { ProviderSchema } = await import(`../../api/${api}/${api}.model.js`);
|
|
187
187
|
const keyModel = getCapVariableName(api); // Assuming this returns a capitalized model name
|
|
188
188
|
models[keyModel] = conn.model(keyModel, ProviderSchema);
|
|
189
|
+
// Mongoose emits 'error' on the model when an autoIndex build fails; with no
|
|
190
|
+
// listener attached EventEmitter rethrows and takes the whole process down.
|
|
191
|
+
// A stale or conflicting index must degrade to a log, not kill startup.
|
|
192
|
+
models[keyModel].on('error', (error) => logger.error(`${keyModel} index build failed: ${error.message}`));
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
return models;
|
package/src/index.js
CHANGED
|
@@ -26,6 +26,8 @@ import UnderpostStatic from './cli/static.js';
|
|
|
26
26
|
import UnderpostTest from './cli/test.js';
|
|
27
27
|
import UnderpostRelease from './cli/release.js';
|
|
28
28
|
import UnderpostSystemProvisionig from './cli/system.js';
|
|
29
|
+
import UnderpostVultr from './cli/vultr.js';
|
|
30
|
+
import UnderpostWireguard from './cli/wireguard.js';
|
|
29
31
|
|
|
30
32
|
import UnderpostDns from './server/dns.js';
|
|
31
33
|
import UnderpostBackup from './server/backup.js';
|
|
@@ -45,7 +47,7 @@ class Underpost {
|
|
|
45
47
|
* @type {String}
|
|
46
48
|
* @memberof Underpost
|
|
47
49
|
*/
|
|
48
|
-
static version = 'v3.
|
|
50
|
+
static version = 'v3.3.0';
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
* Required Node.js major version
|
|
@@ -252,6 +254,26 @@ class Underpost {
|
|
|
252
254
|
return UnderpostSystemProvisionig.API;
|
|
253
255
|
}
|
|
254
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Edge hub WireGuard/HAProxy cli API
|
|
259
|
+
* @static
|
|
260
|
+
* @type {UnderpostWireguard.API}
|
|
261
|
+
* @memberof Underpost
|
|
262
|
+
*/
|
|
263
|
+
static get wireguard() {
|
|
264
|
+
return UnderpostWireguard.API;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Vultr bandwidth guard cli API
|
|
269
|
+
* @static
|
|
270
|
+
* @type {UnderpostVultr.API}
|
|
271
|
+
* @memberof Underpost
|
|
272
|
+
*/
|
|
273
|
+
static get vultr() {
|
|
274
|
+
return UnderpostVultr.API;
|
|
275
|
+
}
|
|
276
|
+
|
|
255
277
|
/**
|
|
256
278
|
* Dns server API
|
|
257
279
|
* @static
|
|
@@ -352,6 +374,8 @@ export {
|
|
|
352
374
|
UnderpostStartUp,
|
|
353
375
|
UnderpostRelease,
|
|
354
376
|
UnderpostTLS,
|
|
377
|
+
UnderpostVultr,
|
|
378
|
+
UnderpostWireguard,
|
|
355
379
|
};
|
|
356
380
|
|
|
357
381
|
export default Underpost;
|
|
@@ -48,6 +48,8 @@ export default {
|
|
|
48
48
|
'/.github/workflows/docker-image.cyberia-server.dev.ci.yml',
|
|
49
49
|
'/.github/workflows/cyberia-client.cd.yml',
|
|
50
50
|
'/.github/workflows/cyberia-server.cd.yml',
|
|
51
|
+
'/.github/workflows/coverall.cyberia.ci.yml',
|
|
52
|
+
'/scripts/coverall-test-cyberia.sh',
|
|
51
53
|
],
|
|
52
54
|
stripPaths: [
|
|
53
55
|
'./src/projects/cyberia',
|
|
@@ -56,8 +58,11 @@ export default {
|
|
|
56
58
|
'./src/runtime/cyberia-client',
|
|
57
59
|
'./src/runtime/engine-cyberia',
|
|
58
60
|
'./test/cyberia-instance-conf-defaults.test.js',
|
|
61
|
+
'./test/cyberia-load.test.js',
|
|
62
|
+
'./test/object-layer-item-id.test.js',
|
|
59
63
|
'./test/shape-generator.test.js',
|
|
60
64
|
'./src/client/public/cyberia-docs',
|
|
65
|
+
'./scripts/coverall-test-cyberia.sh',
|
|
61
66
|
'bin/cyberia.js',
|
|
62
67
|
'./hardhat',
|
|
63
68
|
],
|
|
@@ -18,7 +18,6 @@ import fs from 'fs-extra';
|
|
|
18
18
|
import nodePath from 'path';
|
|
19
19
|
import crypto from 'crypto';
|
|
20
20
|
import { GeminiClient } from './gemini-client.js';
|
|
21
|
-
import { computeSha256 } from './object-layer.js';
|
|
22
21
|
import { loggerFactory } from '../../server/logger.js';
|
|
23
22
|
|
|
24
23
|
const logger = loggerFactory(import.meta);
|
|
@@ -1632,13 +1631,13 @@ function normalizeSagaPayload(raw, { theme }) {
|
|
|
1632
1631
|
|
|
1633
1632
|
/**
|
|
1634
1633
|
* Persist normalized object-layer items into the ObjectLayer collection so they
|
|
1635
|
-
* are editable in the viewer.
|
|
1636
|
-
*
|
|
1634
|
+
* are editable in the viewer. New items get an empty render and an `OFF_CHAIN`
|
|
1635
|
+
* ledger; both can be set later from the object-layer import or from
|
|
1637
1636
|
* `src/client/components/cyberia/ObjectLayerEngineViewer.js`.
|
|
1638
1637
|
*
|
|
1639
|
-
* Upserts
|
|
1640
|
-
*
|
|
1641
|
-
* refreshed
|
|
1638
|
+
* Upserts through `ObjectLayer.upsertByItemId`, so `data.item.id` stays unique
|
|
1639
|
+
* and an existing item's render, ledger and CIDs are PRESERVED — only the
|
|
1640
|
+
* textual stats/item fields are refreshed, and `sha256` is recomputed.
|
|
1642
1641
|
*
|
|
1643
1642
|
* @async
|
|
1644
1643
|
* @param {Object} params
|
|
@@ -1647,28 +1646,20 @@ function normalizeSagaPayload(raw, { theme }) {
|
|
|
1647
1646
|
* @returns {Promise<number>} Count of items created or updated.
|
|
1648
1647
|
*/
|
|
1649
1648
|
async function persistObjectLayers({ objectLayers, ObjectLayer }) {
|
|
1649
|
+
await ObjectLayer.ensureUniqueItemIdIndex();
|
|
1650
|
+
|
|
1650
1651
|
let count = 0;
|
|
1651
1652
|
for (const ol of objectLayers) {
|
|
1652
1653
|
const itemId = ol.item?.id;
|
|
1653
1654
|
if (!itemId) continue;
|
|
1654
1655
|
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
//
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
const data = { stats: ol.stats, item: ol.item, ledger, render };
|
|
1663
|
-
const sha256 = computeSha256(data);
|
|
1664
|
-
|
|
1665
|
-
if (existing) {
|
|
1666
|
-
existing.data = data;
|
|
1667
|
-
existing.sha256 = sha256;
|
|
1668
|
-
await existing.save();
|
|
1669
|
-
} else {
|
|
1670
|
-
await ObjectLayer.create({ data, sha256, cid: null });
|
|
1671
|
-
}
|
|
1656
|
+
// The saga only owns the textual/statistical fields. Ledger and render are
|
|
1657
|
+
// seeded on insert and never refreshed, so a re-import cannot clobber an
|
|
1658
|
+
// on-chain registration or a render produced by the object-layer import.
|
|
1659
|
+
await ObjectLayer.upsertByItemId(
|
|
1660
|
+
{ data: { stats: ol.stats, item: ol.item } },
|
|
1661
|
+
{ setOnInsert: { cid: null, data: { ledger: { type: 'OFF_CHAIN', tokenId: '' }, render: {} } } },
|
|
1662
|
+
);
|
|
1672
1663
|
count++;
|
|
1673
1664
|
}
|
|
1674
1665
|
return count;
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
DefaultCyberiaItems,
|
|
30
30
|
} from '../../client/components/cyberia/SharedDefaultsCyberia.js';
|
|
31
31
|
import { generateFallbackWorld } from '../../api/cyberia-instance/cyberia-fallback-world.js';
|
|
32
|
+
import { getFallbackDefaultItems } from '../../api/cyberia-instance/cyberia-fallback-default-items.js';
|
|
32
33
|
|
|
33
34
|
const logger = loggerFactory(import.meta);
|
|
34
35
|
|
|
@@ -421,6 +422,7 @@ function toInstanceConfig(gc) {
|
|
|
421
422
|
botAggroRange: gc.botAggroRange ?? fb.botAggroRange,
|
|
422
423
|
defaultPlayerWidth: gc.defaultPlayerWidth ?? fb.defaultPlayerWidth,
|
|
423
424
|
defaultPlayerHeight: gc.defaultPlayerHeight ?? fb.defaultPlayerHeight,
|
|
425
|
+
playerBaseSpeed: gc.playerBaseSpeed ?? fb.playerBaseSpeed,
|
|
424
426
|
playerBaseLifeRegenMin: gc.playerBaseLifeRegenMin ?? fb.playerBaseLifeRegenMin,
|
|
425
427
|
playerBaseLifeRegenMax: gc.playerBaseLifeRegenMax ?? fb.playerBaseLifeRegenMax,
|
|
426
428
|
sumStatsLimit: gc.sumStatsLimit ?? fb.sumStatsLimit,
|
|
@@ -553,7 +555,7 @@ async function fetchFullInstance(models, requestedInstanceCode) {
|
|
|
553
555
|
// ── Fallback: instance not found → return a multi-map procedural world ──
|
|
554
556
|
if (!inst) {
|
|
555
557
|
logger.info(`Instance "${instanceCode}" not found — returning fallback world.`);
|
|
556
|
-
const world = generateFallbackWorld();
|
|
558
|
+
const world = generateFallbackWorld({ itemIds: getFallbackDefaultItems() });
|
|
557
559
|
const fallbackConf = buildFallbackConfig();
|
|
558
560
|
|
|
559
561
|
// Collect all objectLayerItemIds from the generated maps so the
|
|
@@ -599,6 +601,23 @@ async function fetchFullInstance(models, requestedInstanceCode) {
|
|
|
599
601
|
|
|
600
602
|
const fallbackConfig = buildFallbackInstanceConfig(fallbackConf, world.instance.itemIds);
|
|
601
603
|
|
|
604
|
+
// Opaque version over everything mutable in this payload, mirroring the
|
|
605
|
+
// persisted path below. A constant here would make hot reload a silent
|
|
606
|
+
// no-op: WorldBuilder.ReloadWorld skips the rebuild — and therefore
|
|
607
|
+
// ApplyInstanceConfig — whenever the version is unchanged. The world
|
|
608
|
+
// geometry itself is deterministic (code defaults + seed), so the inputs
|
|
609
|
+
// that can actually differ are the staged default items and the
|
|
610
|
+
// ObjectLayer docs, which are the only things read from the DB here.
|
|
611
|
+
const fallbackVersionParts = ['fallback'];
|
|
612
|
+
for (const entry of world.instance.itemIds || []) {
|
|
613
|
+
fallbackVersionParts.push(`${entry.id}:${entry.defaultPlayerInventory ? 1 : 0}`);
|
|
614
|
+
}
|
|
615
|
+
for (const doc of fallbackOlDocs) fallbackVersionParts.push(String(doc.sha256 || doc._id));
|
|
616
|
+
const fallbackVersion = `fallback-${crypto
|
|
617
|
+
.createHash('sha256')
|
|
618
|
+
.update(fallbackVersionParts.join('|'))
|
|
619
|
+
.digest('hex')}`;
|
|
620
|
+
|
|
602
621
|
return {
|
|
603
622
|
instance: toInstanceMsg({ ...world.instance, _id: '', seed: instanceCode }),
|
|
604
623
|
maps: world.maps.map((m) => ({
|
|
@@ -613,7 +632,7 @@ async function fetchFullInstance(models, requestedInstanceCode) {
|
|
|
613
632
|
})),
|
|
614
633
|
objectLayers: fallbackOlDocs.map(toObjectLayerMsg),
|
|
615
634
|
config: fallbackConfig,
|
|
616
|
-
version:
|
|
635
|
+
version: fallbackVersion,
|
|
617
636
|
// Mission content for the procedural fallback comes straight from
|
|
618
637
|
// the canonical defaults — no DB, fully self-contained.
|
|
619
638
|
actions: DefaultCyberiaActions.map(toActionMsg),
|
|
@@ -10,9 +10,7 @@ import path from 'path';
|
|
|
10
10
|
import { PNG } from 'pngjs';
|
|
11
11
|
import sharp from 'sharp';
|
|
12
12
|
import { Jimp, intToRGBA, rgbaToInt } from 'jimp';
|
|
13
|
-
import
|
|
14
|
-
import stringify from 'fast-json-stable-stringify';
|
|
15
|
-
|
|
13
|
+
import { computeObjectLayerSha256 } from '../../api/object-layer/object-layer.model.js';
|
|
16
14
|
import { range } from '../../client/components/core/CommonJs.js';
|
|
17
15
|
import {
|
|
18
16
|
generateRandomStats,
|
|
@@ -450,7 +448,7 @@ export class ObjectLayerEngine {
|
|
|
450
448
|
* @memberof CyberiaObjectLayer
|
|
451
449
|
*/
|
|
452
450
|
static computeSha256(data) {
|
|
453
|
-
return
|
|
451
|
+
return computeObjectLayerSha256(data);
|
|
454
452
|
}
|
|
455
453
|
|
|
456
454
|
/**
|
|
@@ -642,23 +640,15 @@ export class ObjectLayerEngine {
|
|
|
642
640
|
}
|
|
643
641
|
|
|
644
642
|
// 4. Atomic create/upsert - ObjectLayer is fully populated with all CIDs
|
|
645
|
-
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
);
|
|
652
|
-
objectLayer = await ObjectLayer.findByIdAndUpdate(existingByItemId._id, objectLayerData, {
|
|
653
|
-
returnDocument: 'after',
|
|
654
|
-
}).populate('objectLayerRenderFramesId');
|
|
655
|
-
if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
|
|
656
|
-
await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
|
|
657
|
-
}
|
|
658
|
-
} else {
|
|
659
|
-
objectLayer = await (await ObjectLayer.create(objectLayerData)).populate('objectLayerRenderFramesId');
|
|
660
|
-
logger.info(`ObjectLayer created successfully with id: ${objectLayer._id}`);
|
|
643
|
+
const existingByItemId = await ObjectLayer.findByItemId(objectLayerData.data.item.id);
|
|
644
|
+
const oldRenderFramesId = existingByItemId?.objectLayerRenderFramesId;
|
|
645
|
+
|
|
646
|
+
const objectLayer = await (await ObjectLayer.upsertByItemId(objectLayerData)).populate('objectLayerRenderFramesId');
|
|
647
|
+
|
|
648
|
+
if (oldRenderFramesId && !oldRenderFramesId.equals(objectLayerRenderFramesDoc._id)) {
|
|
649
|
+
await ObjectLayerRenderFrames.findByIdAndDelete(oldRenderFramesId);
|
|
661
650
|
}
|
|
651
|
+
logger.info(`ObjectLayer for item "${objectLayerData.data.item.id}" persisted with id: ${objectLayer._id}`);
|
|
662
652
|
|
|
663
653
|
return { objectLayer, objectLayerRenderFramesDoc };
|
|
664
654
|
}
|
|
@@ -848,7 +838,7 @@ export class ObjectLayerEngine {
|
|
|
848
838
|
* @memberof CyberiaObjectLayer
|
|
849
839
|
*/
|
|
850
840
|
static async resolveCanonicalCid({ itemId, ObjectLayer, ipfsClient = null, options }) {
|
|
851
|
-
const objectLayer = await ObjectLayer.
|
|
841
|
+
const objectLayer = await ObjectLayer.findByItemId(itemId);
|
|
852
842
|
if (!objectLayer) {
|
|
853
843
|
throw new Error(`ObjectLayer "${itemId}" not found in database`);
|
|
854
844
|
}
|
|
@@ -18,7 +18,10 @@ const TEMPLATE_RESTORE_PATHS = [
|
|
|
18
18
|
`./.github/workflows/gitlab.ci.yml`,
|
|
19
19
|
`./.github/workflows/publish.ci.yml`,
|
|
20
20
|
`./.github/workflows/release.cd.yml`,
|
|
21
|
-
`./
|
|
21
|
+
`./deploy/lib`,
|
|
22
|
+
'./deploy/release',
|
|
23
|
+
'./deploy/pwa-microservices-template',
|
|
24
|
+
'./src/client/services/user/guest.service.js',
|
|
22
25
|
'./src/api/user/guest.service.js',
|
|
23
26
|
'./src/ws/IoInterface.js',
|
|
24
27
|
'./src/ws/IoServer.js',
|
|
@@ -43,7 +43,7 @@ RUN make -f Web.mk all BUILD_MODE=${BUILD_MODE} OUTPUT_DIR=bin/
|
|
|
43
43
|
# --- Runtime Image ---
|
|
44
44
|
FROM rockylinux/rockylinux:9 AS runtime
|
|
45
45
|
|
|
46
|
-
ARG UNDERPOST_VERSION=3.
|
|
46
|
+
ARG UNDERPOST_VERSION=3.3.0
|
|
47
47
|
ARG NODE_VERSION=24.15.0
|
|
48
48
|
RUN set -eux; \
|
|
49
49
|
dnf -y update; \
|
|
@@ -11,7 +11,7 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o server ./cmd/cyberia-se
|
|
|
11
11
|
|
|
12
12
|
# --- Runtime Image ---
|
|
13
13
|
FROM rockylinux/rockylinux:9 AS runtime
|
|
14
|
-
ARG UNDERPOST_VERSION=3.
|
|
14
|
+
ARG UNDERPOST_VERSION=3.3.0
|
|
15
15
|
ARG NODE_VERSION=24.15.0
|
|
16
16
|
|
|
17
17
|
RUN set -eux; \
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.3.0
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.3.0
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# Stage 1 — builder: clone the private deploy, build it, then scrub secrets.
|
|
7
7
|
# ---------------------------------------------------------------------------
|
|
8
8
|
FROM rockylinux/rockylinux:9 AS builder
|
|
9
|
-
ARG UNDERPOST_VERSION=3.
|
|
9
|
+
ARG UNDERPOST_VERSION=3.3.0
|
|
10
10
|
# Pin Node to an exact patch: dnf's nodejs:24 module lags (24.14.1) while
|
|
11
11
|
# underpost's dependencies require >=24.15.0, so install the official binary.
|
|
12
12
|
ARG NODE_VERSION=24.15.0
|
|
@@ -70,6 +70,22 @@ CYBERIA_DEFAULT_INSTANCE=amethyst-strata-expansion
|
|
|
70
70
|
CYBERIA_SERVER_APP_ENV=development
|
|
71
71
|
CYBERIA_SERVER_LOG_LEVEL=
|
|
72
72
|
|
|
73
|
+
# --- cyberia-server WebSocket admission and rate limits ----------------------
|
|
74
|
+
# Unset keeps the built-in default. An explicit 0 turns that one limit off.
|
|
75
|
+
# The startup log prints the effective profile ("ws limits: ...").
|
|
76
|
+
#
|
|
77
|
+
# Set CYBERIA_DISABLE_CONNECTION_LIMITS=1 to turn every limit off. The load test
|
|
78
|
+
# (test/cyberia-load.test.js) drives every simulated client from one address, so
|
|
79
|
+
# it needs this. NEVER enable it on a public deploy.
|
|
80
|
+
CYBERIA_DISABLE_CONNECTION_LIMITS=
|
|
81
|
+
CYBERIA_MAX_CONNECTIONS=
|
|
82
|
+
CYBERIA_MAX_CONNECTIONS_PER_IP=
|
|
83
|
+
CYBERIA_CONNECT_RATE_PER_IP=
|
|
84
|
+
CYBERIA_CONNECT_BURST_PER_IP=
|
|
85
|
+
CYBERIA_MESSAGE_RATE=
|
|
86
|
+
CYBERIA_MESSAGE_BURST=
|
|
87
|
+
CYBERIA_MAX_STRIKES=
|
|
88
|
+
|
|
73
89
|
# --- engine-cyberia runtime env (loaded into the container via env_file) -----
|
|
74
90
|
# The dd-cyberia engine (engine-private/conf/dd-cyberia/conf.server.json) needs
|
|
75
91
|
# these to boot: DB auth + per-site DB names, the base PORT (the cyberia host is
|
|
@@ -4,36 +4,6 @@
|
|
|
4
4
|
# (MongoDB + Valkey + IPFS), then the Cyberia content-authority engine and its
|
|
5
5
|
# per-instance server/client tiers, fronted by an nginx reverse proxy.
|
|
6
6
|
#
|
|
7
|
-
# Canonical location (custom docker-compose workflow):
|
|
8
|
-
# engine-private/conf/dd-cyberia/docker-compose/cyberia/
|
|
9
|
-
# ├── docker-compose.yml (this file — the ENTIRE stack, single source)
|
|
10
|
-
# ├── compose.env (working env-file, used as-is — not generated)
|
|
11
|
-
# ├── nginx.conf (custom per-variant sub-path routing)
|
|
12
|
-
# └── mongodb/entrypoint.sh (replica-set bootstrap)
|
|
13
|
-
# All bind mounts below are relative to this directory: the CLI runs compose with
|
|
14
|
-
# `--project-directory` pinned here (see src/cli/docker-compose.js).
|
|
15
|
-
#
|
|
16
|
-
# Multi-instance: one engine-cyberia (content + asset authority) feeds three
|
|
17
|
-
# cyberia-server + three cyberia-client tiers, one per conf.instances.json
|
|
18
|
-
# multiInstance variant (amethyst-strata-expansion "/", FOREST "/FOREST",
|
|
19
|
-
# TEST "/TEST"). This custom workflow owns nginx.conf and the services below;
|
|
20
|
-
# keep both in sync when its instance topology changes.
|
|
21
|
-
#
|
|
22
|
-
# Startup is a strict health-gated chain: the stable gateway starts after the
|
|
23
|
-
# engine, then each server/client pipeline advances independently:
|
|
24
|
-
# mongodb + valkey -> engine runtime -> proxy -> 3x server -> 3x client
|
|
25
|
-
#
|
|
26
|
-
# Architecture boundaries (see CLAUDE.md "Cyberia architecture boundaries"):
|
|
27
|
-
# engine-cyberia — content, validation, persistence, gRPC(:50051)+REST(:4005)
|
|
28
|
-
# data services, asset metadata. The authority layer.
|
|
29
|
-
# cyberia-server — authoritative real-time simulation / tick processing (Go).
|
|
30
|
-
# cyberia-client — rendering, input, prediction, presentation (WASM bundle).
|
|
31
|
-
#
|
|
32
|
-
# Usage:
|
|
33
|
-
# underpost docker-compose --up --deploy-id dd-cyberia --docker-compose-id cyberia
|
|
34
|
-
# (or the docker:cyberia:* npm scripts). The engine-cyberia image bakes the
|
|
35
|
-
# dd-cyberia build at image-build time, so no private-repo credentials are
|
|
36
|
-
# required at container start.
|
|
37
7
|
|
|
38
8
|
name: dd-cyberia
|
|
39
9
|
|
|
@@ -165,7 +135,7 @@ services:
|
|
|
165
135
|
# server starts but rejects connections until seeded). Serves REST/WS on 4005
|
|
166
136
|
# and the engine gRPC data service on 50051.
|
|
167
137
|
engine-cyberia-runtime:
|
|
168
|
-
image: ${ENGINE_CYBERIA_IMAGE:-underpost/engine-cyberia-dev}:${ENGINE_CYBERIA_TAG:-v3.
|
|
138
|
+
image: ${ENGINE_CYBERIA_IMAGE:-underpost/engine-cyberia-dev}:${ENGINE_CYBERIA_TAG:-v3.3.0}
|
|
169
139
|
container_name: dd-cyberia-engine
|
|
170
140
|
command:
|
|
171
141
|
- /bin/sh
|
|
@@ -220,7 +190,7 @@ services:
|
|
|
220
190
|
# gateway on host port 8081, so one port can route every instance path.
|
|
221
191
|
|
|
222
192
|
cyberia-server-runtime:
|
|
223
|
-
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.
|
|
193
|
+
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.3.0}
|
|
224
194
|
container_name: dd-cyberia-server
|
|
225
195
|
environment:
|
|
226
196
|
INSTANCE_CODE: amethyst-strata-expansion
|
|
@@ -232,6 +202,14 @@ services:
|
|
|
232
202
|
STATIC_DIR: ${CYBERIA_SERVER_STATIC_DIR:-/home/dd/engine/cyberia-server/public}
|
|
233
203
|
APP_ENV: ${CYBERIA_SERVER_APP_ENV:-development}
|
|
234
204
|
LOG_LEVEL: ${CYBERIA_SERVER_LOG_LEVEL:-}
|
|
205
|
+
CYBERIA_DISABLE_CONNECTION_LIMITS: ${CYBERIA_DISABLE_CONNECTION_LIMITS:-}
|
|
206
|
+
CYBERIA_MAX_CONNECTIONS: ${CYBERIA_MAX_CONNECTIONS:-}
|
|
207
|
+
CYBERIA_MAX_CONNECTIONS_PER_IP: ${CYBERIA_MAX_CONNECTIONS_PER_IP:-}
|
|
208
|
+
CYBERIA_CONNECT_RATE_PER_IP: ${CYBERIA_CONNECT_RATE_PER_IP:-}
|
|
209
|
+
CYBERIA_CONNECT_BURST_PER_IP: ${CYBERIA_CONNECT_BURST_PER_IP:-}
|
|
210
|
+
CYBERIA_MESSAGE_RATE: ${CYBERIA_MESSAGE_RATE:-}
|
|
211
|
+
CYBERIA_MESSAGE_BURST: ${CYBERIA_MESSAGE_BURST:-}
|
|
212
|
+
CYBERIA_MAX_STRIKES: ${CYBERIA_MAX_STRIKES:-}
|
|
235
213
|
networks:
|
|
236
214
|
- dd-cyberia-internal
|
|
237
215
|
expose:
|
|
@@ -248,7 +226,7 @@ services:
|
|
|
248
226
|
restart: unless-stopped
|
|
249
227
|
|
|
250
228
|
cyberia-server-forest:
|
|
251
|
-
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.
|
|
229
|
+
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.3.0}
|
|
252
230
|
container_name: dd-cyberia-server-forest
|
|
253
231
|
environment:
|
|
254
232
|
INSTANCE_CODE: FOREST
|
|
@@ -260,6 +238,14 @@ services:
|
|
|
260
238
|
STATIC_DIR: ${CYBERIA_SERVER_STATIC_DIR:-/home/dd/engine/cyberia-server/public}
|
|
261
239
|
APP_ENV: ${CYBERIA_SERVER_APP_ENV:-development}
|
|
262
240
|
LOG_LEVEL: ${CYBERIA_SERVER_LOG_LEVEL:-}
|
|
241
|
+
CYBERIA_DISABLE_CONNECTION_LIMITS: ${CYBERIA_DISABLE_CONNECTION_LIMITS:-}
|
|
242
|
+
CYBERIA_MAX_CONNECTIONS: ${CYBERIA_MAX_CONNECTIONS:-}
|
|
243
|
+
CYBERIA_MAX_CONNECTIONS_PER_IP: ${CYBERIA_MAX_CONNECTIONS_PER_IP:-}
|
|
244
|
+
CYBERIA_CONNECT_RATE_PER_IP: ${CYBERIA_CONNECT_RATE_PER_IP:-}
|
|
245
|
+
CYBERIA_CONNECT_BURST_PER_IP: ${CYBERIA_CONNECT_BURST_PER_IP:-}
|
|
246
|
+
CYBERIA_MESSAGE_RATE: ${CYBERIA_MESSAGE_RATE:-}
|
|
247
|
+
CYBERIA_MESSAGE_BURST: ${CYBERIA_MESSAGE_BURST:-}
|
|
248
|
+
CYBERIA_MAX_STRIKES: ${CYBERIA_MAX_STRIKES:-}
|
|
263
249
|
networks:
|
|
264
250
|
- dd-cyberia-internal
|
|
265
251
|
expose:
|
|
@@ -276,7 +262,7 @@ services:
|
|
|
276
262
|
restart: unless-stopped
|
|
277
263
|
|
|
278
264
|
cyberia-server-test:
|
|
279
|
-
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.
|
|
265
|
+
image: ${CYBERIA_SERVER_IMAGE:-underpost/cyberia-server-dev}:${CYBERIA_SERVER_TAG:-v3.3.0}
|
|
280
266
|
container_name: dd-cyberia-server-test
|
|
281
267
|
environment:
|
|
282
268
|
INSTANCE_CODE: TEST
|
|
@@ -288,6 +274,14 @@ services:
|
|
|
288
274
|
STATIC_DIR: ${CYBERIA_SERVER_STATIC_DIR:-/home/dd/engine/cyberia-server/public}
|
|
289
275
|
APP_ENV: ${CYBERIA_SERVER_APP_ENV:-development}
|
|
290
276
|
LOG_LEVEL: ${CYBERIA_SERVER_LOG_LEVEL:-}
|
|
277
|
+
CYBERIA_DISABLE_CONNECTION_LIMITS: ${CYBERIA_DISABLE_CONNECTION_LIMITS:-}
|
|
278
|
+
CYBERIA_MAX_CONNECTIONS: ${CYBERIA_MAX_CONNECTIONS:-}
|
|
279
|
+
CYBERIA_MAX_CONNECTIONS_PER_IP: ${CYBERIA_MAX_CONNECTIONS_PER_IP:-}
|
|
280
|
+
CYBERIA_CONNECT_RATE_PER_IP: ${CYBERIA_CONNECT_RATE_PER_IP:-}
|
|
281
|
+
CYBERIA_CONNECT_BURST_PER_IP: ${CYBERIA_CONNECT_BURST_PER_IP:-}
|
|
282
|
+
CYBERIA_MESSAGE_RATE: ${CYBERIA_MESSAGE_RATE:-}
|
|
283
|
+
CYBERIA_MESSAGE_BURST: ${CYBERIA_MESSAGE_BURST:-}
|
|
284
|
+
CYBERIA_MAX_STRIKES: ${CYBERIA_MAX_STRIKES:-}
|
|
291
285
|
networks:
|
|
292
286
|
- dd-cyberia-internal
|
|
293
287
|
expose:
|
|
@@ -315,7 +309,7 @@ services:
|
|
|
315
309
|
# cyberia-server-test -> cyberia-client-test
|
|
316
310
|
|
|
317
311
|
cyberia-client-runtime:
|
|
318
|
-
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.
|
|
312
|
+
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.3.0}
|
|
319
313
|
container_name: dd-cyberia-client
|
|
320
314
|
environment:
|
|
321
315
|
CYBERIA_PORT: '8081'
|
|
@@ -340,7 +334,7 @@ services:
|
|
|
340
334
|
restart: unless-stopped
|
|
341
335
|
|
|
342
336
|
cyberia-client-forest:
|
|
343
|
-
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.
|
|
337
|
+
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.3.0}
|
|
344
338
|
container_name: dd-cyberia-client-forest
|
|
345
339
|
environment:
|
|
346
340
|
CYBERIA_PORT: '8081'
|
|
@@ -365,7 +359,7 @@ services:
|
|
|
365
359
|
restart: unless-stopped
|
|
366
360
|
|
|
367
361
|
cyberia-client-test:
|
|
368
|
-
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.
|
|
362
|
+
image: ${CYBERIA_CLIENT_IMAGE:-underpost/cyberia-client-dev}:${CYBERIA_CLIENT_TAG:-v3.3.0}
|
|
369
363
|
container_name: dd-cyberia-client-test
|
|
370
364
|
environment:
|
|
371
365
|
CYBERIA_PORT: '8081'
|
package/src/server/backup.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
8
|
import { loggerFactory } from './logger.js';
|
|
9
9
|
import Underpost from '../index.js';
|
|
10
|
-
import { loadCronDeployEnv } from './
|
|
10
|
+
import { loadCronDeployEnv } from './cron.js';
|
|
11
11
|
|
|
12
12
|
const logger = loggerFactory(import.meta);
|
|
13
13
|
|