@underpostnet/cyberia 3.3.0 → 3.3.76
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/.dockerignore +1 -0
- package/.env.example +17 -5
- package/.github/workflows/coverall.cyberia.ci.yml +39 -14
- package/.github/workflows/cyberia-client.cd.yml +5 -0
- package/.github/workflows/cyberia-server.cd.yml +5 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
- package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
- package/.github/workflows/engine-cyberia.cd.yml +3 -0
- package/.github/workflows/engine-cyberia.ci.yml +4 -5
- package/.github/workflows/ghpkg.ci.yml +35 -20
- package/.github/workflows/hardhat.ci.yml +12 -11
- package/.github/workflows/npmpkg.ci.yml +17 -15
- package/.github/workflows/publish.cyberia.ci.yml +44 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -0
- package/.prettierignore +1 -0
- package/AGENTS.md +96 -0
- package/CHANGELOG.md +653 -2513
- package/CLI-HELP.md +323 -157
- package/Dockerfile +25 -9
- package/Dockerfile.dev +25 -9
- package/Dockerfile.test +5 -5
- package/README.md +48 -28
- package/bin/build.js +86 -41
- package/bin/build.template.js +8 -3
- package/bin/cyberia.js +1494 -1403
- package/bin/deploy.js +18 -104
- package/bin/index.js +1494 -1403
- package/compose.env +17 -5
- package/conf.js +98 -7
- package/deploy/cyberia-client/deploy.sh +46 -0
- package/deploy/cyberia-client/package.sh +17 -0
- package/deploy/cyberia-client/state.sh +15 -0
- package/deploy/cyberia-server/deploy.sh +46 -0
- package/deploy/cyberia-server/package.sh +17 -0
- package/deploy/cyberia-server/state.sh +15 -0
- package/deploy/dd-cyberia/deploy.sh +9 -29
- package/deploy/dd-cyberia/init.sh +38 -45
- package/deploy/dd-cyberia/package.sh +16 -0
- package/deploy/dd-cyberia/state.sh +14 -0
- package/deploy/dd-cyberia/sync-deploy.sh +133 -147
- package/deploy/lib/config.sh +29 -0
- package/deploy/lib/github-actions-logging.sh +610 -0
- package/deploy/lib/host.sh +194 -0
- package/deploy/lib/state.sh +65 -0
- package/deploy/pwa-microservices-template/deploy.sh +17 -42
- package/deploy/release/deploy.sh +9 -41
- package/deployment.yaml +7 -2
- package/docker-compose.yml +23 -17
- package/examples/static-page/README.md +19 -19
- package/examples/static-page/ssr-components/CustomPage.js +2 -2
- package/hardhat/hardhat.config.js +1 -6
- package/hardhat/package-lock.json +101 -40
- package/hardhat/package.json +2 -2
- package/manifests/alertmanager/deployment.yaml +81 -0
- package/manifests/blackbox-exporter/deployment.yaml +75 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +46 -27
- package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
- package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
- package/manifests/deployment/mongo-express/service.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
- package/manifests/grafana/deployment.yaml +26 -7
- package/manifests/grafana/kustomization.yaml +1 -0
- package/manifests/grafana/service.yaml +6 -1
- package/manifests/mariadb/pv.yaml +1 -0
- package/manifests/mongodb/statefulset.yaml +9 -2
- package/manifests/mysql/pv-pvc.yaml +14 -1
- package/manifests/postgresql/pv.yaml +12 -1
- package/manifests/postgresql/pvc.yaml +1 -0
- package/manifests/prometheus/deployment.yaml +18 -22
- package/package.json +87 -12
- package/scripts/event-monitor.sh +56 -0
- package/scripts/k3s-node-setup.sh +27 -14
- package/scripts/kubeadm-node-setup.sh +31 -11
- package/scripts/maas-setup.sh +8 -8
- package/scripts/selinux-normalize.sh +907 -0
- package/scripts/shutdown-machine.sh +843 -0
- package/scripts/test-monitor.sh +5 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
- package/src/api/core/core.controller.js +1 -1
- package/src/api/core/core.router.js +2 -2
- package/src/api/core/core.service.js +2 -2
- package/src/api/crypto/crypto.controller.js +1 -1
- package/src/api/crypto/crypto.service.js +1 -1
- package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +3 -3
- package/src/api/cyberia-action/cyberia-action.service.js +5 -6
- package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
- package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
- package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
- package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
- package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
- package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
- package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
- package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
- package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
- package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
- package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
- package/src/api/cyberia-map/cyberia-map.router.js +1 -1
- package/src/api/cyberia-map/cyberia-map.service.js +8 -4
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
- package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
- package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
- package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
- package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
- package/src/api/default/default.controller.js +1 -1
- package/src/api/default/default.router.js +1 -1
- package/src/api/default/default.service.js +2 -2
- package/src/api/document/document.controller.js +1 -1
- package/src/api/document/document.router.js +1 -1
- package/src/api/document/document.service.js +2 -2
- package/src/api/file/file.controller.js +1 -1
- package/src/api/file/file.ref.js +153 -0
- package/src/api/file/file.ref.json +11 -2
- package/src/api/file/file.router.js +1 -1
- package/src/api/file/file.service.js +2 -2
- package/src/api/instance/instance.controller.js +1 -1
- package/src/api/instance/instance.router.js +1 -1
- package/src/api/instance/instance.service.js +2 -2
- package/src/api/ipfs/ipfs.controller.js +1 -1
- package/src/api/ipfs/ipfs.router.js +2 -2
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +1 -1
- package/src/api/object-layer/object-layer.model.js +47 -12
- package/src/api/object-layer/object-layer.router.js +12 -5
- package/src/api/object-layer/object-layer.service.js +116 -123
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
- package/src/api/test/test.controller.js +1 -1
- package/src/api/test/test.service.js +1 -1
- package/src/api/user/guest.service.js +3 -3
- package/src/api/user/user.controller.js +1 -1
- package/src/api/user/user.router.js +2 -2
- package/src/api/user/user.service.js +4 -4
- package/src/api.js +5 -9
- package/src/cli/app.js +402 -0
- package/src/cli/baremetal.js +30 -35
- package/src/cli/client.js +306 -0
- package/src/cli/cloud-init.js +3 -3
- package/src/cli/cluster.js +191 -82
- package/src/cli/db.js +120 -68
- package/src/cli/deploy.js +157 -75
- package/src/cli/docker-compose.js +5 -5
- package/src/cli/domains.js +184 -0
- package/src/cli/dotenv-store.js +143 -0
- package/src/cli/event.js +2281 -0
- package/src/cli/fs-selection.js +115 -0
- package/src/cli/fs.js +159 -343
- package/src/cli/host.js +672 -0
- package/src/cli/image.js +4 -6
- package/src/cli/index.js +343 -151
- package/src/cli/ipfs.js +34 -30
- package/src/cli/kickstart.js +1 -1
- package/src/cli/kubectl.js +218 -41
- package/src/cli/lxd.js +3 -3
- package/src/cli/monitor.js +1359 -26
- package/src/cli/package.js +90 -0
- package/src/cli/release.js +16 -12
- package/src/cli/repository.js +586 -363
- package/src/cli/run.js +398 -843
- package/src/cli/secrets.js +2158 -964
- package/src/cli/ssh.js +478 -279
- package/src/cli/state.js +394 -0
- package/src/cli/static.js +2 -2
- package/src/cli/system.js +1 -1
- package/src/cli/test.js +203 -125
- package/src/cli/vultr.js +61 -21
- package/src/cli/wireguard.js +1112 -306
- package/src/client/components/core/CalendarCore.js +53 -96
- package/src/client/components/core/Docs.js +327 -303
- package/src/client/components/core/FileExplorer.js +0 -21
- package/src/client/components/core/Modal.js +56 -1
- package/src/client/components/core/PanelForm.js +4 -4
- package/src/client/components/core/Repository.js +56 -0
- package/src/client/components/core/Translate.js +7 -0
- package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
- package/src/client/components/core/Wallet.js +0 -11
- package/src/client/components/core/Worker.js +7 -1
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
- package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
- package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
- package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
- package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
- package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -1
- package/src/client/components/default/SettingsDefault.js +2 -2
- package/src/client/components/itemledger/SettingsItemledger.js +2 -2
- package/src/client/components/underpost/AppShellUnderpost.js +3 -2
- package/src/client/components/underpost/SettingsUnderpost.js +2 -2
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
- package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-384x384.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-512x512.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/default/assets/background/white.jpg +0 -0
- package/src/client/public/default/browserconfig.xml +1 -1
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon-48x48.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/manifest.webmanifest +5 -5
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/yandex-browser-50x50.png +0 -0
- package/src/client/public/default/yandex-browser-manifest.json +1 -1
- package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
- package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
- package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -10
- package/src/client/services/object-layer/object-layer.service.js +3 -1
- package/src/client/ssr/RootDocument.js +1 -1
- package/src/client/ssr/body/404.js +1 -1
- package/src/client/ssr/body/500.js +1 -1
- package/src/client/ssr/body/CacheControl.js +1 -1
- package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
- package/src/client/ssr/head/CryptokoynScripts.js +1 -1
- package/src/client/ssr/head/Css.js +1 -1
- package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +1 -1
- package/src/client/ssr/head/ItemledgerScripts.js +1 -1
- package/src/client/ssr/head/Microdata.js +1 -1
- package/src/client/ssr/head/Production.js +1 -1
- package/src/client/ssr/head/Pwa.js +1 -1
- package/src/client/ssr/head/PwaItemledger.js +1 -1
- package/src/client/ssr/head/Seo.js +1 -1
- package/src/client/ssr/head/UnderpostScripts.js +1 -1
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
- package/src/client/ssr/views/Cyberia404.js +7 -5
- package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/views/Maintenance.js +1 -1
- package/src/client/ssr/views/NoNetworkConnection.js +1 -1
- package/src/client/ssr/views/Test.js +1 -1
- package/src/client/sw/core.sw.js +20 -14
- package/src/client-builder/client-build-docs.js +92 -77
- package/src/client-builder/client-build-live.js +2 -2
- package/src/client-builder/client-build.js +105 -74
- package/src/client-builder/client-bundle.js +347 -0
- package/src/client-builder/client-dev-server.js +3 -3
- package/src/client-builder/client-icons.js +2 -2
- package/src/client-builder/ssr.js +3 -3
- package/src/client.build.js +3 -6
- package/src/client.dev.js +3 -6
- package/src/db/DataBaseProvider.js +186 -3
- package/src/db/mariadb/MariaDB.js +3 -2
- package/src/db/mongo/MongoBootstrap.js +273 -101
- package/src/db/mongo/MongoExpress.js +187 -0
- package/src/db/mongo/MongooseDB.js +7 -8
- package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
- package/src/grpc/cyberia/grpc-server.js +6 -8
- package/src/index.js +79 -23
- package/src/mailer/EmailRender.js +2 -2
- package/src/mailer/MailerInterceptor.js +87 -0
- package/src/mailer/MailerProvider.js +50 -6
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
- package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
- package/src/projects/cyberia/besu-genesis-generator.js +8 -17
- package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
- package/src/projects/cyberia/catalog-cyberia.js +54 -10
- package/src/projects/cyberia/gemini-client.js +4 -4
- package/src/projects/cyberia/generate-saga.js +5 -12
- package/src/projects/cyberia/hot-reload-trigger.js +18 -29
- package/src/projects/cyberia/instance-backup.js +210 -0
- package/src/projects/cyberia/instance-data.js +178 -258
- package/src/projects/cyberia/ipfs-client.js +4 -4
- package/src/projects/cyberia/map-preview-generator.js +33 -69
- package/src/projects/cyberia/object-layer.js +153 -320
- package/src/projects/cyberia/seed-audio.js +139 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
- package/src/projects/cyberia/semantic-layer-generator.js +3 -19
- package/src/projects/cyberia/stat-balance.js +81 -0
- package/src/projects/cyberia/stat-commands.js +23 -0
- package/src/projects/cyberia/stat-contract-generator.js +101 -0
- package/src/projects/underpost/catalog-underpost.js +9 -1
- package/src/proxy.js +4 -7
- package/src/runtime/cyberia-client/Dockerfile +17 -8
- package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
- package/src/runtime/cyberia-server/Dockerfile +18 -6
- package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
- package/src/runtime/engine-cyberia/Dockerfile +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
- package/src/runtime/engine-cyberia/compose.env +17 -5
- package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
- package/src/runtime/express/Express.js +32 -27
- package/src/runtime/lampp/Lampp.js +22 -70
- package/src/runtime/nginx/Nginx.js +1 -1
- package/src/runtime/wp/Wp.js +16 -48
- package/src/server/{catalog.js → build/catalog.js} +15 -5
- package/src/server/build/coverage.js +188 -0
- package/src/server/build/execution.js +402 -0
- package/src/server/build/package.js +508 -0
- package/src/server/build/testing.js +578 -0
- package/src/server/{dns.js → network/dns.js} +144 -11
- package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
- package/src/server/{middlewares.js → network/middlewares.js} +11 -5
- package/src/server/network/node-capability.js +98 -0
- package/src/server/{peer.js → network/peer.js} +3 -3
- package/src/server/{proxy.js → network/proxy.js} +7 -13
- package/src/server/network/router.js +356 -0
- package/src/server/{tls.js → network/tls.js} +2 -2
- package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
- package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
- package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
- package/src/server/{cri.js → ops/cri.js} +2 -2
- package/src/server/{cron.js → ops/cron.js} +349 -74
- package/src/server/ops/event-notification.js +284 -0
- package/src/server/{logger.js → ops/logger.js} +143 -23
- package/src/server/ops/monitoring.js +1724 -0
- package/src/server/{systemd.js → ops/systemd.js} +55 -1
- package/src/server/{conf.js → runtime/conf.js} +516 -423
- package/src/server/runtime/config-scope.js +215 -0
- package/src/server/runtime/environment.js +149 -0
- package/src/server/{process.js → runtime/process.js} +153 -12
- package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
- package/src/server/{runtime.js → runtime/runtime.js} +12 -8
- package/src/server/{start.js → runtime/start.js} +128 -39
- package/src/server/{auth.js → security/auth.js} +7 -8
- package/src/server/security/container-storage.js +382 -0
- package/src/server/{crypto.js → security/crypto.js} +1 -1
- package/src/server/{selinux.js → security/selinux.js} +1 -1
- package/src/server/{backup.js → storage/backup.js} +17 -8
- package/src/server/{data-query.js → storage/data-query.js} +17 -1
- package/src/server/storage/downloader.js +121 -0
- package/src/server/storage/repository.js +68 -0
- package/src/server/storage/zip.js +153 -0
- package/src/server.js +4 -7
- package/src/ws/IoInterface.js +1 -1
- package/src/ws/IoServer.js +1 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/src/ws/default/default.ws.connection.js +1 -1
- package/src/ws/default/default.ws.emit.js +1 -1
- package/src/ws/default/default.ws.server.js +1 -1
- package/test/e2e/event-e2e-public-ingress-down.js +45 -0
- package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
- package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
- package/test/{api.test.js → integration/app/api.test.js} +33 -14
- package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
- package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
- package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
- package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
- package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
- package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
- package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
- package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
- package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
- package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
- package/test/integration/app/cyberia/seed-audio.test.js +275 -0
- package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
- package/test/integration/infra/1-security/config-scope.test.js +305 -0
- package/test/integration/infra/1-security/container-storage.test.js +356 -0
- package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
- package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
- package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
- package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
- package/test/integration/infra/1-security/systemd-service.test.js +70 -0
- package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
- package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
- package/test/integration/infra/2-network/node-capability.test.js +182 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
- package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
- package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
- package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
- package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
- package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
- package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
- package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
- package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
- package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
- package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
- package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
- package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
- package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
- package/test/integration/infra/5-observability/event-notification.test.js +197 -0
- package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
- package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
- package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
- package/test/support/shell-harness.js +73 -0
- package/test/unit/build-template.test.js +97 -0
- package/test/unit/build-workflow-offline.test.js +132 -0
- package/test/unit/catalog.test.js +71 -0
- package/test/unit/client-build-docs.test.js +361 -0
- package/test/unit/client-bundle.test.js +313 -0
- package/test/unit/conf-loading.test.js +303 -0
- package/test/unit/conf-resolution.test.js +996 -0
- package/test/unit/coverage-artifact.test.js +221 -0
- package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
- package/test/unit/cyberia/instance-backup.test.js +183 -0
- package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
- package/test/unit/cyberia/publish-workflow.test.js +22 -0
- package/test/unit/cyberia/stat-balance.test.js +69 -0
- package/test/unit/deploy-env-resolution.test.js +38 -0
- package/test/unit/deploy-log-table.test.js +518 -0
- package/test/unit/downloader-integrity.test.js +98 -0
- package/test/unit/execution-profiles.test.js +219 -0
- package/test/unit/file-reference-registry.test.js +141 -0
- package/test/unit/fleet-sync-source.test.js +149 -0
- package/test/unit/fs-storage-paths.test.js +596 -0
- package/test/unit/logger-redaction.test.js +141 -0
- package/test/unit/package.test.js +457 -0
- package/test/unit/prepare-host.test.js +382 -0
- package/test/unit/process-environment.test.js +18 -0
- package/test/unit/propagation-message.test.js +78 -0
- package/test/unit/redeploy-plan.test.js +24 -0
- package/test/unit/release-bump.test.js +474 -0
- package/test/unit/ssh-output-redaction.test.js +28 -0
- package/test/unit/start-options.test.js +46 -0
- package/test/unit/test-tiers.test.js +220 -0
- package/test/unit/zip-archive.test.js +142 -0
- package/vitest.config.js +66 -0
- package/.nycrc +0 -9
- package/deploy/lib/logging.sh +0 -96
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
- package/manifests/mongodb/pv-pvc.yaml +0 -59
- package/scripts/coverall-test-cyberia.sh +0 -24
- package/scripts/coverall-test.sh +0 -24
- package/scripts/link-local-underpost-cli.sh +0 -6
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
- package/src/api/user/user.build.js +0 -16
- package/src/cli/env.js +0 -177
- package/src/client/components/core/Blockchain.js +0 -41
- package/src/client/components/core/Blog.js +0 -9
- package/src/client/components/core/KeyboardAvoidance.js +0 -145
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/white0-min.jpg +0 -0
- package/src/client/public/default/assets/background/white0.jpg +0 -0
- package/src/client/public/doc/favicon.ico +0 -0
- package/src/client/public/doc/sitemap +0 -148
- package/src/server/downloader.js +0 -73
- package/src/server/environment.js +0 -98
package/src/cli/test.js
CHANGED
|
@@ -1,174 +1,252 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runs the test tiers, wherever they have to run: on this host, inside a
|
|
3
|
+
* deployment's containers, or as a Job on the cluster.
|
|
4
|
+
*
|
|
5
|
+
* One entrypoint, one runner. Selecting suites, ordering tiers and rendering
|
|
6
|
+
* the reporting surfaces belong to `src/server/build/testing.js`; this module resolves
|
|
7
|
+
* where the run happens and drives it.
|
|
8
|
+
*
|
|
3
9
|
* @module src/cli/test.js
|
|
4
10
|
* @namespace UnderpostTest
|
|
5
11
|
*/
|
|
6
12
|
|
|
7
13
|
import fs from 'fs-extra';
|
|
14
|
+
import nodePath from 'node:path';
|
|
8
15
|
import { timer } from '../client/components/core/CommonJs.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
16
|
+
import { getUnderpostRootPath } from '../server/runtime/environment.js';
|
|
17
|
+
import { actionInitLog, loggerFactory, setUpInfo } from '../server/ops/logger.js';
|
|
18
|
+
import { shellExec } from '../server/runtime/process.js';
|
|
19
|
+
import {
|
|
20
|
+
UNDERPOST_TESTING,
|
|
21
|
+
allureManifestsFactory,
|
|
22
|
+
coverageReportKey,
|
|
23
|
+
resolveTestSelection,
|
|
24
|
+
testJobManifestFactory,
|
|
25
|
+
vitestArgsFactory,
|
|
26
|
+
} from '../server/build/testing.js';
|
|
13
27
|
import Underpost from '../index.js';
|
|
28
|
+
|
|
14
29
|
const logger = loggerFactory(import.meta);
|
|
15
30
|
|
|
16
31
|
/**
|
|
17
32
|
* @class UnderpostTest
|
|
18
|
-
* @description Manages
|
|
33
|
+
* @description Manages test execution and its cluster-side reporting.
|
|
19
34
|
* @memberof UnderpostTest
|
|
20
35
|
*/
|
|
21
36
|
class UnderpostTest {
|
|
22
37
|
static API = {
|
|
23
38
|
/**
|
|
24
|
-
* Logs information about the current process environment to the console.
|
|
25
|
-
*
|
|
26
|
-
* This function is used to log details about
|
|
27
|
-
* the execution context, such as command-line arguments,
|
|
28
|
-
* environment variables, the process's administrative privileges,
|
|
29
|
-
* and the maximum available heap space size.
|
|
30
|
-
*
|
|
31
|
-
* @static
|
|
32
39
|
* @method setUpInfo
|
|
40
|
+
* @description Logs the execution context a failing run has to be read against:
|
|
41
|
+
* arguments, environment, privileges and heap ceiling.
|
|
33
42
|
* @returns {Promise<void>}
|
|
34
43
|
* @memberof UnderpostTest
|
|
35
44
|
*/
|
|
36
45
|
async setUpInfo() {
|
|
37
46
|
return await setUpInfo(logger);
|
|
38
47
|
},
|
|
48
|
+
|
|
39
49
|
/**
|
|
40
50
|
* @method run
|
|
41
|
-
* @description Runs the
|
|
51
|
+
* @description Runs the selected tiers on this host.
|
|
52
|
+
*
|
|
53
|
+
* Resolved against the globally installed engine when the current directory
|
|
54
|
+
* is not one, so `underpost test` from anywhere still runs the shipped suites
|
|
55
|
+
* rather than failing on a missing config.
|
|
56
|
+
* @param {object} [params]
|
|
57
|
+
* @param {string} [params.suite] - Suite or tier selector.
|
|
58
|
+
* @param {string} [params.grep] - Substring filter on test names.
|
|
59
|
+
* @param {boolean} [params.watch] - Keep the runner open and re-run on change.
|
|
60
|
+
* @param {boolean} [params.coverage] - Emit the coverage reporters.
|
|
61
|
+
* @param {boolean} [params.allure] - Also write Allure results for the dashboard.
|
|
62
|
+
* @returns {void}
|
|
63
|
+
* @throws {Error} When no engine tree with a runner configuration can be found.
|
|
42
64
|
* @memberof UnderpostTest
|
|
43
65
|
*/
|
|
44
|
-
run() {
|
|
66
|
+
run({ suite = '', grep = '', watch = false, coverage = true, allure = false } = {}) {
|
|
45
67
|
actionInitLog();
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
const root = [process.cwd(), getUnderpostRootPath()].find(
|
|
69
|
+
(candidate) => candidate && fs.existsSync(`${candidate}/vitest.config.js`),
|
|
70
|
+
);
|
|
71
|
+
if (!root) throw new Error('[test] no vitest.config.js in the current directory or the global underpost install');
|
|
72
|
+
|
|
73
|
+
const { projects, runVitest, delegated } = resolveTestSelection(suite);
|
|
74
|
+
const allureResultsDirectory =
|
|
75
|
+
allure &&
|
|
76
|
+
nodePath.resolve(
|
|
77
|
+
root,
|
|
78
|
+
process.env[UNDERPOST_TESTING.allureResultsEnvKey] || UNDERPOST_TESTING.allureResultsDirectory,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (runVitest) {
|
|
82
|
+
const env = [
|
|
83
|
+
'NODE_ENV=test',
|
|
84
|
+
...(allureResultsDirectory ? [`${UNDERPOST_TESTING.allureResultsEnvKey}=${allureResultsDirectory}`] : []),
|
|
85
|
+
];
|
|
86
|
+
// Only this selection's report starts from nothing: the ones beside it belong to
|
|
87
|
+
// other selections a deploy on this host may publish.
|
|
88
|
+
if (coverage) fs.removeSync(`${root}/${UNDERPOST_TESTING.coverageDirectory}/${coverageReportKey(suite)}`);
|
|
89
|
+
shellExec(
|
|
90
|
+
`cd ${root} && ${env.join(' ')} npx vitest ${vitestArgsFactory({ projects, grep, watch, coverage }).join(' ')}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for (const { name, directory, delegate } of delegated) {
|
|
95
|
+
const tierRoot = `${root}/${directory}`;
|
|
96
|
+
// A product build strips the tiers it does not own, so an absent
|
|
97
|
+
// directory is a tier this tree does not ship, not a failure.
|
|
98
|
+
if (!fs.existsSync(tierRoot)) {
|
|
99
|
+
logger.warn(`Skipping tier not present in this tree`, { tier: name, directory });
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (allureResultsDirectory) fs.mkdirSync(allureResultsDirectory, { recursive: true });
|
|
103
|
+
const resultsPath = allureResultsDirectory ? `${allureResultsDirectory}/TEST-${name}.xml` : '';
|
|
104
|
+
shellExec(`cd ${tierRoot} && ${delegate({ resultsPath, grep })}`);
|
|
52
105
|
}
|
|
53
106
|
},
|
|
107
|
+
|
|
54
108
|
/**
|
|
55
|
-
* @method
|
|
56
|
-
* @description
|
|
57
|
-
*
|
|
58
|
-
* @param {object}
|
|
59
|
-
* @param {
|
|
60
|
-
* @param {
|
|
61
|
-
* @param {boolean}
|
|
62
|
-
* @
|
|
63
|
-
* @param {string} options.podStatus - The status of the pod to test.
|
|
64
|
-
* @param {string} options.kindType - The type of the kind to test.
|
|
65
|
-
* @param {number} options.deltaMs - The delta time in milliseconds.
|
|
66
|
-
* @param {number} options.maxAttempts - The maximum number of attempts.
|
|
109
|
+
* @method dashboard
|
|
110
|
+
* @description Applies the Allure dashboard: the results claim every run
|
|
111
|
+
* writes to, the report server, and the ways in.
|
|
112
|
+
* @param {object} params
|
|
113
|
+
* @param {string} [params.namespace='default'] - Target namespace.
|
|
114
|
+
* @param {string} [params.host] - Hostname to route the dashboard sub-path on.
|
|
115
|
+
* @param {boolean} [params.dryRun] - Print the manifests instead of applying them.
|
|
116
|
+
* @returns {string} The rendered manifests.
|
|
67
117
|
* @memberof UnderpostTest
|
|
68
118
|
*/
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
typeof options.podName === 'string' &&
|
|
85
|
-
options.podStatus &&
|
|
86
|
-
typeof options.podStatus === 'string'
|
|
87
|
-
)
|
|
88
|
-
return await Underpost.test.statusMonitor(options.podName, options.podStatus, options.kindType);
|
|
119
|
+
dashboard({ namespace = 'default', host = '', dryRun = false } = {}) {
|
|
120
|
+
const manifests = allureManifestsFactory({ namespace, host });
|
|
121
|
+
if (dryRun) {
|
|
122
|
+
console.log(manifests);
|
|
123
|
+
return manifests;
|
|
124
|
+
}
|
|
125
|
+
shellExec(`sudo kubectl apply -f - <<'EOF'\n${manifests}\nEOF`);
|
|
126
|
+
const { allure } = UNDERPOST_TESTING;
|
|
127
|
+
logger.info('Allure dashboard applied', {
|
|
128
|
+
namespace,
|
|
129
|
+
nodePort: allure.nodePort,
|
|
130
|
+
url: host ? `https://${host}${allure.subPath}` : '',
|
|
131
|
+
});
|
|
132
|
+
return manifests;
|
|
133
|
+
},
|
|
89
134
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
135
|
+
/**
|
|
136
|
+
* @method job
|
|
137
|
+
* @description Runs one suite on the cluster as a Job.
|
|
138
|
+
*
|
|
139
|
+
* The Job writes into the same claim the dashboard reads, so its results are
|
|
140
|
+
* published by finishing — there is no upload step to fail separately from
|
|
141
|
+
* the tests it would have reported.
|
|
142
|
+
* @param {object} params
|
|
143
|
+
* @param {string} params.image - Image carrying the engine and its dependencies.
|
|
144
|
+
* @param {string} [params.suite] - Suite or tier selector.
|
|
145
|
+
* @param {string} [params.namespace='default'] - Target namespace.
|
|
146
|
+
* @param {string} [params.nodeName] - Pins the pod to one node.
|
|
147
|
+
* @param {boolean} [params.dryRun] - Print the manifest instead of applying it.
|
|
148
|
+
* @returns {Promise<boolean>} Whether the Job's pod reached completion.
|
|
149
|
+
* @throws {Error} When no image is given.
|
|
150
|
+
* @memberof UnderpostTest
|
|
151
|
+
*/
|
|
152
|
+
async job({ image = '', suite = '', namespace = 'default', nodeName = '', dryRun = false } = {}) {
|
|
153
|
+
if (!image) throw new Error('[test] --job needs --image: the Job has no engine tree of its own');
|
|
154
|
+
const name = `${UNDERPOST_TESTING.job.namePrefix}-${(suite || 'all').replace(/[^a-z0-9]+/g, '-')}-${Date.now()}`;
|
|
155
|
+
const manifest = testJobManifestFactory({ name, namespace, image, suite, nodeName });
|
|
156
|
+
if (dryRun) {
|
|
157
|
+
console.log(manifest);
|
|
158
|
+
return true;
|
|
97
159
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!deployId) continue;
|
|
102
|
-
if (options.itc === true)
|
|
103
|
-
switch (deployId) {
|
|
104
|
-
case 'dd-lampp':
|
|
105
|
-
{
|
|
106
|
-
const { MARIADB_HOST, MARIADB_USER, MARIADB_PASSWORD, DD_LAMPP_TEST_DB_0 } = process.env;
|
|
160
|
+
shellExec(`sudo kubectl apply -f - <<'EOF'\n${manifest}\nEOF`);
|
|
161
|
+
return await Underpost.test.statusMonitor(name, 'Completed', 'pods');
|
|
162
|
+
},
|
|
107
163
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
164
|
+
/**
|
|
165
|
+
* @method callback
|
|
166
|
+
* @description `underpost test` entrypoint.
|
|
167
|
+
* @param {string} [suite] - Suite or tier selector.
|
|
168
|
+
* @param {object} [options]
|
|
169
|
+
* @param {boolean} [options.itc] - Run here rather than dispatching into pods.
|
|
170
|
+
* @param {string} [options.deployList] - Comma separated deploy ids to run inside.
|
|
171
|
+
* @param {boolean} [options.dashboard] - Apply the Allure dashboard and exit.
|
|
172
|
+
* @param {boolean} [options.job] - Run the suite as a cluster Job.
|
|
173
|
+
* @param {boolean} [options.allure] - Write Allure results alongside the run.
|
|
174
|
+
* @param {string} [options.grep] - Substring filter on test names.
|
|
175
|
+
* @param {boolean} [options.watch] - Keep the runner open and re-run on change.
|
|
176
|
+
* @param {boolean} [options.coverage] - Emit the coverage reporters.
|
|
177
|
+
* @param {string} [options.namespace] - Namespace for the cluster-side actions.
|
|
178
|
+
* @param {string} [options.image] - Image for `--job`.
|
|
179
|
+
* @param {string} [options.nodeName] - Node pin for `--job`.
|
|
180
|
+
* @param {string} [options.host] - Hostname for the dashboard route.
|
|
181
|
+
* @param {boolean} [options.dryRun] - Render manifests without applying them.
|
|
182
|
+
* @param {string} [options.podName] - Wait for this object instead of running tests.
|
|
183
|
+
* @param {string} [options.podStatus] - Status `--pod-name` waits for.
|
|
184
|
+
* @param {string} [options.kindType] - Kind `--pod-name` queries.
|
|
185
|
+
* @returns {Promise<void>}
|
|
186
|
+
* @memberof UnderpostTest
|
|
187
|
+
*/
|
|
188
|
+
async callback(suite = '', options = {}) {
|
|
189
|
+
const { itc, deployList, dashboard, job, podName, podStatus, kindType, namespace = 'default' } = options;
|
|
116
190
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
191
|
+
if (podName) return void (await Underpost.test.statusMonitor(podName, podStatus || 'Running', kindType));
|
|
192
|
+
if (dashboard) return void Underpost.test.dashboard(options);
|
|
193
|
+
if (job) return void (await Underpost.test.job({ ...options, suite }));
|
|
121
194
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
else logger.warn(`Couldn't find pods in deployment`, { deployId });
|
|
195
|
+
if (deployList && !itc) {
|
|
196
|
+
for (const deployId of deployList
|
|
197
|
+
.split(',')
|
|
198
|
+
.map((value) => value.trim())
|
|
199
|
+
.filter(Boolean)) {
|
|
200
|
+
const pods = Underpost.kubectl.get(deployId, 'pods', namespace);
|
|
201
|
+
if (pods.length === 0) {
|
|
202
|
+
logger.warn(`Couldn't find pods in deployment`, { deployId });
|
|
203
|
+
continue;
|
|
134
204
|
}
|
|
205
|
+
for (const { NAME } of pods)
|
|
206
|
+
Underpost.kubectl.exec({
|
|
207
|
+
podName: NAME,
|
|
208
|
+
namespace,
|
|
209
|
+
command: `cd ${UNDERPOST_TESTING.job.workingDirectory} && underpost test ${suite} --itc`,
|
|
210
|
+
});
|
|
135
211
|
}
|
|
136
|
-
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return void Underpost.test.run({ ...options, suite });
|
|
137
216
|
},
|
|
217
|
+
|
|
138
218
|
/**
|
|
139
219
|
* @method statusMonitor
|
|
140
|
-
* @description
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* @param {
|
|
220
|
+
* @description Waits for a cluster object to reach a status.
|
|
221
|
+
*
|
|
222
|
+
* `Completed` is accepted wherever `Running` was asked for: a Job's pod and a
|
|
223
|
+
* one-shot container both satisfy "it came up" by having finished, and a
|
|
224
|
+
* caller polling for readiness would otherwise time out on a success.
|
|
225
|
+
* @param {string} podName - Name, or name substring, of the object to watch.
|
|
226
|
+
* @param {string} [status='Running'] - Status to wait for.
|
|
227
|
+
* @param {string} [kindType='pods'] - Kind to query.
|
|
228
|
+
* @param {number} [deltaMs=1000] - Delay between attempts.
|
|
229
|
+
* @param {number} [maxAttempts=300] - Attempts before giving up.
|
|
230
|
+
* @returns {Promise<boolean>} Whether the status was reached.
|
|
146
231
|
* @memberof UnderpostTest
|
|
147
232
|
*/
|
|
148
|
-
statusMonitor(podName, status = 'Running', kindType = '', deltaMs = 1000, maxAttempts = 60 * 5) {
|
|
149
|
-
if (!
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
logger.error(`Failed to test pod ${podName} within ${maxAttempts} attempts`);
|
|
166
|
-
return resolve(false);
|
|
167
|
-
}
|
|
168
|
-
return _monitor();
|
|
169
|
-
};
|
|
170
|
-
await _monitor();
|
|
171
|
-
});
|
|
233
|
+
async statusMonitor(podName, status = 'Running', kindType = 'pods', deltaMs = 1000, maxAttempts = 60 * 5) {
|
|
234
|
+
if (!kindType) kindType = 'pods';
|
|
235
|
+
logger.info(`Loading instance`, { podName, status, kindType, deltaMs, maxAttempts });
|
|
236
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
237
|
+
await timer(deltaMs);
|
|
238
|
+
const pods = Underpost.kubectl.get(podName, kindType);
|
|
239
|
+
const reached = pods.find(
|
|
240
|
+
(pod) => pod.STATUS === status || (status === 'Running' && pod.STATUS === 'Completed'),
|
|
241
|
+
);
|
|
242
|
+
logger.info(
|
|
243
|
+
`Testing pod ${podName}... ${reached ? 1 : 0}/1 - elapsed time ${deltaMs * attempt}ms - attempt ${attempt}/${maxAttempts}`,
|
|
244
|
+
pods[0] ? pods[0].STATUS : 'Not found kind object',
|
|
245
|
+
);
|
|
246
|
+
if (reached) return true;
|
|
247
|
+
}
|
|
248
|
+
logger.error(`Failed to test pod ${podName} within ${maxAttempts} attempts`);
|
|
249
|
+
return false;
|
|
172
250
|
},
|
|
173
251
|
};
|
|
174
252
|
}
|
package/src/cli/vultr.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* This module is that meter. It reads the instance's consumption from the Vultr
|
|
11
11
|
* API, compares it against the plan's quota, and — once a configured fraction of
|
|
12
12
|
* it is gone — reaches the VPS over SSH and drops its egress with
|
|
13
|
-
* {@link module:src/server/dns.js}'s `blockAllEgress`.
|
|
13
|
+
* {@link module:src/server/network/dns.js}'s `blockAllEgress`.
|
|
14
14
|
*
|
|
15
15
|
* That last step is deliberately blunt: it takes every hostname behind the hub
|
|
16
16
|
* offline. It is the cheaper failure. An overage accrues silently and without a
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* inbound SSH session still completes its handshake and the host stays
|
|
20
20
|
* reachable to undo it.
|
|
21
21
|
*
|
|
22
|
-
* The enforcement is latched in the
|
|
22
|
+
* The enforcement is latched in the host store rather than re-applied every run,
|
|
23
23
|
* so a cron firing every ten minutes does not re-open an SSH session to a host
|
|
24
24
|
* that is already blocked.
|
|
25
25
|
*
|
|
@@ -28,9 +28,12 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import axios from 'axios';
|
|
31
|
-
import { environmentValueFactory } from '../server/environment.js';
|
|
32
|
-
import { FORWARD_PROXY, fetchViaForwardProxy } from '../server/forward-proxy.js';
|
|
33
|
-
import
|
|
31
|
+
import { environmentValueFactory } from '../server/runtime/environment.js';
|
|
32
|
+
import { FORWARD_PROXY, fetchViaForwardProxy } from '../server/network/forward-proxy.js';
|
|
33
|
+
import fs from 'fs-extra';
|
|
34
|
+
import nodePath from 'node:path';
|
|
35
|
+
import { loggerFactory } from '../server/ops/logger.js';
|
|
36
|
+
import { UNDERPOST_MONITORING } from '../server/ops/monitoring.js';
|
|
34
37
|
import Underpost from '../index.js';
|
|
35
38
|
|
|
36
39
|
const logger = loggerFactory(import.meta);
|
|
@@ -55,9 +58,8 @@ const UNDERPOST_VULTR = {
|
|
|
55
58
|
requestTimeoutMs: 20000,
|
|
56
59
|
defaultSshUser: 'root',
|
|
57
60
|
defaultSshPort: 22,
|
|
58
|
-
defaultSshKeyPath: './engine-private/deploy/id_rsa',
|
|
59
61
|
remoteEnginePath: '/home/dd/engine',
|
|
60
|
-
//
|
|
62
|
+
// latched in the host store, which the CronJob mounts from the host, so the
|
|
61
63
|
// decision survives the container that made it.
|
|
62
64
|
latchKey: 'VULTR_EGRESS_BLOCKED_AT',
|
|
63
65
|
env: {
|
|
@@ -80,13 +82,13 @@ const UNDERPOST_VULTR = {
|
|
|
80
82
|
* @method envFactory
|
|
81
83
|
* @description First non-empty value among a list of keys.
|
|
82
84
|
*
|
|
83
|
-
* Resolution is {@link module:src/server/environment.js.environmentValueFactory}'s — the process
|
|
84
|
-
* environment, then the deploy env `underpost env <
|
|
85
|
-
* selects into `./.env`, then the
|
|
85
|
+
* Resolution is {@link module:src/server/runtime/environment.js.environmentValueFactory}'s — the process
|
|
86
|
+
* environment, then the deploy env `underpost app load --env <environment>`
|
|
87
|
+
* selects into `./.env`, then the host store — rather than a second
|
|
86
88
|
* implementation of it, because the three callers differ: a CronJob container has
|
|
87
89
|
* its deploy env loaded into `process.env` by `loadCronDeployEnv`, an operator
|
|
88
|
-
* preparing a manual run has `./.env`, and an operator who ran `underpost
|
|
89
|
-
* set` has the
|
|
90
|
+
* preparing a manual run has `./.env`, and an operator who ran `underpost host
|
|
91
|
+
* set` has the host store. Never logged — one of the keys this resolves is an API
|
|
90
92
|
* key.
|
|
91
93
|
* @param {string|Array<string>} keys - Environment variable name, or names in precedence order.
|
|
92
94
|
* @returns {string} The resolved value, or an empty string.
|
|
@@ -294,7 +296,7 @@ const vultrRequest = async ({ apiKey, path, params = {}, proxy = null }) => {
|
|
|
294
296
|
const code = error?.code || error?.cause?.code;
|
|
295
297
|
const proxyHint =
|
|
296
298
|
proxy?.apiKey && ['EHOSTUNREACH', 'ENETUNREACH', 'ECONNREFUSED', 'ETIMEDOUT'].includes(code)
|
|
297
|
-
? '; verify wg0 on the
|
|
299
|
+
? '; verify wg0 on the node; if only pods fail, re-run --wireguard-setup and restart wg0; if the host also fails, re-run --forward-proxy-server on the hub'
|
|
298
300
|
: '';
|
|
299
301
|
throw new Error(
|
|
300
302
|
`[vultr] GET /v2${path} failed${responseStatus ? ` (${responseStatus})` : ''}: ${detail}${proxyHint}`,
|
|
@@ -353,7 +355,7 @@ class UnderpostVultr {
|
|
|
353
355
|
* {@link UnderpostCron} job does, so `underpost cron default vultr` dispatches
|
|
354
356
|
* to it unchanged. The deploy list is not used to select an instance — the
|
|
355
357
|
* edge hub is one machine for the whole cluster, exactly as its WireGuard
|
|
356
|
-
*
|
|
358
|
+
* WireGuard topology is — but it is logged so a run is attributable.
|
|
357
359
|
* @param {string} [deployList] - Comma-separated deploy ids, from the cron dispatcher.
|
|
358
360
|
* @param {object} [options] - CLI flags.
|
|
359
361
|
* @returns {Promise<object>} Result from {@link UnderpostVultr.checkBandwidth}.
|
|
@@ -363,6 +365,43 @@ class UnderpostVultr {
|
|
|
363
365
|
return await UnderpostVultr.API.checkBandwidth({ ...options, deployList });
|
|
364
366
|
},
|
|
365
367
|
|
|
368
|
+
/**
|
|
369
|
+
* @method publishBandwidthMetrics
|
|
370
|
+
* @description Publishes the measured quota so the cluster can read it
|
|
371
|
+
* without calling Vultr.
|
|
372
|
+
*
|
|
373
|
+
* The API is rate limited and needs a credential, neither of which belongs
|
|
374
|
+
* on an alert evaluation path, so the guard — which already holds the
|
|
375
|
+
* numbers — writes them where the host collector picks them up, and to the
|
|
376
|
+
* host configuration store for anything that reads configuration rather than metrics.
|
|
377
|
+
* The file is renamed into place because the collector may read it mid-write.
|
|
378
|
+
* @param {{consumedBytes: number, maxBytes: number}} state - Measured quota state.
|
|
379
|
+
* @returns {boolean} True when the metrics file was written.
|
|
380
|
+
* @memberof UnderpostVultr
|
|
381
|
+
*/
|
|
382
|
+
publishBandwidthMetrics({ consumedBytes = 0, maxBytes = 0 } = {}) {
|
|
383
|
+
Underpost.host.store.set('VULTR_BANDWIDTH_USAGE_BYTES', `${consumedBytes}`);
|
|
384
|
+
Underpost.host.store.set('VULTR_BANDWIDTH_LIMIT_BYTES', `${maxBytes}`);
|
|
385
|
+
|
|
386
|
+
const target = `${UNDERPOST_MONITORING.nodeExporter.textfileDirectory}/vultr_bandwidth.prom`;
|
|
387
|
+
const content =
|
|
388
|
+
'# HELP vultr_bandwidth_used_bytes Monthly bandwidth consumed by the edge hub.\n' +
|
|
389
|
+
'# TYPE vultr_bandwidth_used_bytes gauge\n' +
|
|
390
|
+
`vultr_bandwidth_used_bytes ${consumedBytes}\n` +
|
|
391
|
+
'# HELP vultr_bandwidth_limit_bytes Monthly bandwidth quota of the edge hub plan.\n' +
|
|
392
|
+
'# TYPE vultr_bandwidth_limit_bytes gauge\n' +
|
|
393
|
+
`vultr_bandwidth_limit_bytes ${maxBytes}\n`;
|
|
394
|
+
try {
|
|
395
|
+
fs.mkdirpSync(nodePath.dirname(target));
|
|
396
|
+
fs.writeFileSync(`${target}.tmp`, content, 'utf8');
|
|
397
|
+
fs.renameSync(`${target}.tmp`, target);
|
|
398
|
+
return true;
|
|
399
|
+
} catch (error) {
|
|
400
|
+
logger.warn('Bandwidth metrics not published to the host collector', { target, error: `${error.message}` });
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
|
|
366
405
|
/**
|
|
367
406
|
* @method resolveConfig
|
|
368
407
|
* @description Every input the guard needs, resolved once.
|
|
@@ -382,10 +421,9 @@ class UnderpostVultr {
|
|
|
382
421
|
threshold: thresholdFactory(options.threshold || envFactory(UNDERPOST_VULTR.env.threshold)),
|
|
383
422
|
host: `${options.host || ''}`.trim() || envFactory(UNDERPOST_VULTR.env.host),
|
|
384
423
|
user: `${options.user || ''}`.trim() || envFactory(UNDERPOST_VULTR.env.user) || UNDERPOST_VULTR.defaultSshUser,
|
|
385
|
-
keyPath:
|
|
386
|
-
`${options.keyPath || ''}`.trim() ||
|
|
387
|
-
|
|
388
|
-
UNDERPOST_VULTR.defaultSshKeyPath,
|
|
424
|
+
keyPath: Underpost.ssh.keyPathFactory(
|
|
425
|
+
`${options.keyPath || ''}`.trim() || envFactory(UNDERPOST_VULTR.env.keyPath),
|
|
426
|
+
),
|
|
389
427
|
port: Number(options.port || envFactory(UNDERPOST_VULTR.env.port)) || UNDERPOST_VULTR.defaultSshPort,
|
|
390
428
|
// `total` is the conservative reading and trips first; `outgoing` counts
|
|
391
429
|
// egress alone, which is what a plan billing outbound-only meters.
|
|
@@ -441,7 +479,9 @@ class UnderpostVultr {
|
|
|
441
479
|
const totals = bandwidthTotalsFactory({ bandwidth, month: config.month });
|
|
442
480
|
const consumedBytes = config.metric === 'outgoing' ? totals.outgoingBytes : totals.totalBytes;
|
|
443
481
|
const state = quotaStateFactory({ consumedBytes, planBandwidthGB, threshold: config.threshold });
|
|
444
|
-
|
|
482
|
+
UnderpostVultr.API.publishBandwidthMetrics(state);
|
|
483
|
+
const latchedAt =
|
|
484
|
+
`${Underpost.host.store.get(UNDERPOST_VULTR.latchKey, undefined, { disableLog: true }) ?? ''}`.trim();
|
|
445
485
|
|
|
446
486
|
const summary = {
|
|
447
487
|
instanceId: config.instanceId,
|
|
@@ -472,7 +512,7 @@ class UnderpostVultr {
|
|
|
472
512
|
// real trigger, so it is cleared as soon as usage is back under the
|
|
473
513
|
// threshold — but the host stays blocked until someone says otherwise.
|
|
474
514
|
if (latchedAt) {
|
|
475
|
-
if (!config.dryRun) Underpost.
|
|
515
|
+
if (!config.dryRun) Underpost.host.store.delete(UNDERPOST_VULTR.latchKey);
|
|
476
516
|
if (config.autoUnblock) await UnderpostVultr.API.setEdgeEgress({ config, blocked: false });
|
|
477
517
|
else
|
|
478
518
|
logger.warn('Edge egress is still blocked from a previous cycle; unblock it when you are ready', {
|
|
@@ -496,7 +536,7 @@ class UnderpostVultr {
|
|
|
496
536
|
}
|
|
497
537
|
|
|
498
538
|
const enforced = await UnderpostVultr.API.setEdgeEgress({ config, blocked: true });
|
|
499
|
-
if (enforced && !config.dryRun) Underpost.
|
|
539
|
+
if (enforced && !config.dryRun) Underpost.host.store.set(UNDERPOST_VULTR.latchKey, new Date().toISOString());
|
|
500
540
|
return { ...state, ...summary, enforced, latched: enforced };
|
|
501
541
|
},
|
|
502
542
|
|