@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/app.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App domain: one application deployment's runtime environment.
|
|
3
|
+
*
|
|
4
|
+
* Its durable source is that deployment's env file under `engine-private/conf/<deployId>/`.
|
|
5
|
+
* The deployment id is resolved from the repository context, never passed as a path, so a
|
|
6
|
+
* caller says `--env development` and gets `.env.development` — or its sub-configuration
|
|
7
|
+
* variant when `--args sub-conf=<name>` names one.
|
|
8
|
+
*
|
|
9
|
+
* A custom instance is a deployment too: `--args instance-id=<id>` addresses that instance's own
|
|
10
|
+
* `instances/<id>/env/<env>.env` and its own `<deployId>-<instanceId>-<env>-env` Secret, so an
|
|
11
|
+
* instance's runtime environment is managed through this domain rather than by reaching into the
|
|
12
|
+
* private conf tree by hand.
|
|
13
|
+
*
|
|
14
|
+
* Implements the canonical domain action set; see {@link UnderpostDomains.DOMAIN_ACTIONS}.
|
|
15
|
+
* @module src/cli/app.js
|
|
16
|
+
* @namespace UnderpostApp
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import dotenv from 'dotenv';
|
|
20
|
+
import fs from 'fs-extra';
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
cleanDeployEnvFiles,
|
|
24
|
+
DEFAULT_DEPLOY_ID,
|
|
25
|
+
deployEnvContentFactory,
|
|
26
|
+
deployEnvFilePath,
|
|
27
|
+
deployOciEnvFilePath,
|
|
28
|
+
instanceEnvFilePath,
|
|
29
|
+
loadConf,
|
|
30
|
+
} from '../server/runtime/conf.js';
|
|
31
|
+
import { domainContextFactory } from './domains.js';
|
|
32
|
+
import { loggerFactory } from '../server/ops/logger.js';
|
|
33
|
+
import { readDeployRoutes } from '../server/network/router.js';
|
|
34
|
+
import { shellExec } from '../server/runtime/process.js';
|
|
35
|
+
import { writeEnv } from '../server/runtime/environment.js';
|
|
36
|
+
import { isReservedEnvKey } from './host.js';
|
|
37
|
+
import Underpost from '../index.js';
|
|
38
|
+
|
|
39
|
+
const logger = loggerFactory(import.meta);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Name of the Kubernetes Secret a deployment's environment is projected into. An instance carries
|
|
43
|
+
* its own, under the `<deployId>-<instanceId>` prefix every other instance object already uses.
|
|
44
|
+
*/
|
|
45
|
+
const appSecretName = (deployId, env, instanceId = '') =>
|
|
46
|
+
`${instanceId ? `${deployId}-${instanceId}` : deployId}-${env}-env`;
|
|
47
|
+
|
|
48
|
+
// This domain's local runtime: the working-tree file `loadConf` materializes and the server
|
|
49
|
+
// reads. `publish` is the inverse of `load`, so both ends name the same file.
|
|
50
|
+
const LOCAL_RUNTIME_ENV_PATH = './.env';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @class UnderpostApp
|
|
54
|
+
* @description Application deployment environment domain.
|
|
55
|
+
* @memberof UnderpostApp
|
|
56
|
+
*/
|
|
57
|
+
class UnderpostApp {
|
|
58
|
+
static API = {
|
|
59
|
+
/**
|
|
60
|
+
* Resolves the deployment id from the repository/deployment context.
|
|
61
|
+
*
|
|
62
|
+
* Most specific first: an explicit `--args deploy-id=`, the ambient `DEPLOY_ID` a loaded
|
|
63
|
+
* environment exports, the host store the node was bootstrapped with, then the first routed
|
|
64
|
+
* deploy. Falls back to the default deploy id, so resolution is total.
|
|
65
|
+
* @param {object} [context] - Normalized domain context, or `{ args }`.
|
|
66
|
+
* @returns {string} Deployment id.
|
|
67
|
+
* @memberof UnderpostApp
|
|
68
|
+
*/
|
|
69
|
+
deployId(context = {}) {
|
|
70
|
+
const routed = readDeployRoutes();
|
|
71
|
+
return (
|
|
72
|
+
`${context.args?.['deploy-id'] ?? context.deployId ?? ''}`.trim() ||
|
|
73
|
+
`${process.env.DEPLOY_ID || ''}`.trim() ||
|
|
74
|
+
`${Underpost.host.store.get('DEPLOY_ID', undefined, { disableLog: true }) || ''}`.trim() ||
|
|
75
|
+
(routed.length > 0 ? routed[0] : '') ||
|
|
76
|
+
DEFAULT_DEPLOY_ID
|
|
77
|
+
);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Resolves the custom instance this invocation addresses, if any.
|
|
82
|
+
* @param {object} [context] - Normalized domain context, or `{ args }`.
|
|
83
|
+
* @returns {string} Instance id, or the empty string for the deployment itself.
|
|
84
|
+
* @memberof UnderpostApp
|
|
85
|
+
*/
|
|
86
|
+
instanceId(context = {}) {
|
|
87
|
+
return `${context.args?.['instance-id'] ?? context.instanceId ?? ''}`.trim();
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolves the durable source for an environment.
|
|
92
|
+
*
|
|
93
|
+
* `--args instance-id=` selects that instance's own env file. Otherwise a named
|
|
94
|
+
* sub-configuration selects `.env.<env>.<subConf>` when that file exists and degrades
|
|
95
|
+
* to the plain `.env.<env>` when it does not — the same precedence
|
|
96
|
+
* {@link ServerConfBuilder.loadConf} applies, so both agree on which file is in effect.
|
|
97
|
+
* @param {object} [context] - Normalized domain context.
|
|
98
|
+
* @returns {string} Path to the deployment or instance env file.
|
|
99
|
+
* @memberof UnderpostApp
|
|
100
|
+
*/
|
|
101
|
+
envPath(context = {}) {
|
|
102
|
+
const env = `${context.env ?? ''}`.trim() || 'production';
|
|
103
|
+
const instanceId = UnderpostApp.API.instanceId(context);
|
|
104
|
+
if (instanceId) return instanceEnvFilePath(UnderpostApp.API.deployId(context), instanceId, env);
|
|
105
|
+
return deployEnvFilePath(
|
|
106
|
+
UnderpostApp.API.deployId(context),
|
|
107
|
+
env,
|
|
108
|
+
`${context.args?.['sub-conf'] ?? process.env.DEPLOY_SUB_CONF ?? ''}`.trim(),
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Resolves the environment for a container runtime: the durable source with its
|
|
114
|
+
* `.env.<env>.oci` overlay applied. Used wherever the consumer is a container image rather
|
|
115
|
+
* than this host — the cluster Secret projection above all.
|
|
116
|
+
* @param {object} [context] - Normalized domain context.
|
|
117
|
+
* @returns {{source: string, overlay: string|null, content: string, values: Object<string,string>}}
|
|
118
|
+
* The resolved environment.
|
|
119
|
+
* @memberof UnderpostApp
|
|
120
|
+
*/
|
|
121
|
+
ociEnv(context = {}) {
|
|
122
|
+
// An instance env file is already the container's environment — `instance-build-manifest`
|
|
123
|
+
// derives it for that runtime — so there is no host/container split to overlay away.
|
|
124
|
+
const source = UnderpostApp.API.envPath(context);
|
|
125
|
+
if (UnderpostApp.API.instanceId(context))
|
|
126
|
+
return {
|
|
127
|
+
source,
|
|
128
|
+
overlay: null,
|
|
129
|
+
content: fs.existsSync(source) ? fs.readFileSync(source, 'utf8') : '',
|
|
130
|
+
values: UnderpostApp.API.read(context),
|
|
131
|
+
};
|
|
132
|
+
return deployEnvContentFactory(
|
|
133
|
+
UnderpostApp.API.deployId(context),
|
|
134
|
+
`${context.env ?? ''}`.trim() || 'production',
|
|
135
|
+
`${context.args?.['sub-conf'] ?? process.env.DEPLOY_SUB_CONF ?? ''}`.trim(),
|
|
136
|
+
{ oci: true },
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Parses a deployment's environment. An absent source reads as `{}`.
|
|
142
|
+
* @param {object} [context] - Normalized domain context.
|
|
143
|
+
* @returns {Object<string, string>} Parsed deployment environment.
|
|
144
|
+
* @memberof UnderpostApp
|
|
145
|
+
*/
|
|
146
|
+
read(context = {}) {
|
|
147
|
+
const envPath = UnderpostApp.API.envPath(context);
|
|
148
|
+
return fs.existsSync(envPath) ? dotenv.parse(fs.readFileSync(envPath, 'utf8')) : {};
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
// ── canonical domain actions ────────────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Onboards the app domain: resolves the deployment id, confirms its environment source
|
|
155
|
+
* exists, then loads it. Idempotent.
|
|
156
|
+
* @param {object} context - Normalized domain context.
|
|
157
|
+
* @returns {{deployId: string, source: string, keys: number}} What was onboarded.
|
|
158
|
+
* @memberof UnderpostApp
|
|
159
|
+
*/
|
|
160
|
+
setup(context = {}) {
|
|
161
|
+
context = domainContextFactory(context);
|
|
162
|
+
const deployId = UnderpostApp.API.deployId(context);
|
|
163
|
+
const source = UnderpostApp.API.envPath(context);
|
|
164
|
+
if (!fs.existsSync(source)) throw new Error(`[app] deployment environment not found: ${source}`);
|
|
165
|
+
if (context.dryRun) {
|
|
166
|
+
logger.info('[dry-run] app setup would load', { deployId, source });
|
|
167
|
+
return { deployId, source, keys: Object.keys(UnderpostApp.API.read(context)).length };
|
|
168
|
+
}
|
|
169
|
+
const { keys } = UnderpostApp.API.load(context);
|
|
170
|
+
return { deployId, source, keys };
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Materializes the deployment environment into this domain's local runtime: the working-tree
|
|
175
|
+
* `./.env` copies and the in-process `Config.default` the server reads.
|
|
176
|
+
*
|
|
177
|
+
* Deterministic: the same environment selector and repository context always resolve the
|
|
178
|
+
* same file, and the working tree is rebuilt from it rather than merged into.
|
|
179
|
+
* @param {object} context - Normalized domain context.
|
|
180
|
+
* @returns {{source: string, keys: number}} Which file was loaded and how much of it.
|
|
181
|
+
* @memberof UnderpostApp
|
|
182
|
+
*/
|
|
183
|
+
load(context = {}) {
|
|
184
|
+
context = domainContextFactory(context);
|
|
185
|
+
const deployId = UnderpostApp.API.deployId(context);
|
|
186
|
+
const envPath = UnderpostApp.API.envPath(context);
|
|
187
|
+
if (!fs.existsSync(envPath)) throw new Error(`[app] deployment environment not found: ${envPath}`);
|
|
188
|
+
const values = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
189
|
+
if (context.dryRun) {
|
|
190
|
+
logger.info('[dry-run] app load would materialize the working tree', {
|
|
191
|
+
deployId,
|
|
192
|
+
source: envPath,
|
|
193
|
+
keys: Object.keys(values).length,
|
|
194
|
+
});
|
|
195
|
+
return { source: envPath, keys: Object.keys(values).length };
|
|
196
|
+
}
|
|
197
|
+
// Deliberately not the host configuration store: that store is host-scoped and holds the node's
|
|
198
|
+
// own configuration, so writing a deployment's environment there would erase it.
|
|
199
|
+
process.env.NODE_ENV = context.env;
|
|
200
|
+
const instanceId = UnderpostApp.API.instanceId(context);
|
|
201
|
+
// `loadConf` materializes a deployment's working tree from its own conf; an instance has no
|
|
202
|
+
// conf of its own, so its file is the local runtime env directly.
|
|
203
|
+
if (instanceId) writeEnv(LOCAL_RUNTIME_ENV_PATH, values);
|
|
204
|
+
else loadConf(deployId, `${context.args['sub-conf'] ?? ''}`.trim() || undefined);
|
|
205
|
+
// The resolution loadConf performed, not `ociEnv()`, which forces the overlay on: a
|
|
206
|
+
// skipped overlay and an applied one were indistinguishable in the pod log.
|
|
207
|
+
const resolved = deployEnvContentFactory(deployId, context.env, `${context.args?.['sub-conf'] ?? ''}`.trim());
|
|
208
|
+
const inContainer = Underpost.state.isInsideContainer();
|
|
209
|
+
logger.info('Deployment environment loaded', {
|
|
210
|
+
deployId,
|
|
211
|
+
instanceId: instanceId || null,
|
|
212
|
+
source: envPath,
|
|
213
|
+
inContainer,
|
|
214
|
+
ociOverlay: resolved.overlay,
|
|
215
|
+
keys: Object.keys(values).length,
|
|
216
|
+
});
|
|
217
|
+
// A container that resolves no overlay runs on the host-scoped endpoints of the base file —
|
|
218
|
+
// a loopback database, a local cache — and fails minutes later at the first connection,
|
|
219
|
+
// pointing at the endpoint rather than at the conf checkout that is missing the overlay.
|
|
220
|
+
// Named rather than thrown: a deployment is allowed to have no overlay for an environment.
|
|
221
|
+
if (inContainer && !instanceId && !resolved.overlay)
|
|
222
|
+
logger.warn('No OCI env overlay resolved; container is running on host-scoped values', {
|
|
223
|
+
deployId,
|
|
224
|
+
env: context.env,
|
|
225
|
+
expected: deployOciEnvFilePath(deployId, context.env),
|
|
226
|
+
});
|
|
227
|
+
return { source: envPath, keys: Object.keys(values).length };
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Writes this domain's local runtime back into the deployment's durable source.
|
|
232
|
+
*
|
|
233
|
+
* The exact inverse of `load`, so it reads the working-tree `./.env` that `load` materialized
|
|
234
|
+
* — never the host configuration store, which belongs to the host domain and carries the node's
|
|
235
|
+
* configuration rather than this deployment's.
|
|
236
|
+
* Refuses to overwrite an existing source without `--force`.
|
|
237
|
+
* @param {object} context - Normalized domain context.
|
|
238
|
+
* @returns {{target: string, keys: number}} What was written.
|
|
239
|
+
* @memberof UnderpostApp
|
|
240
|
+
*/
|
|
241
|
+
publish(context = {}) {
|
|
242
|
+
context = domainContextFactory(context);
|
|
243
|
+
const target = UnderpostApp.API.envPath(context);
|
|
244
|
+
const source = LOCAL_RUNTIME_ENV_PATH;
|
|
245
|
+
if (!fs.existsSync(source))
|
|
246
|
+
throw new Error(`[app] ${source} not found; run \`underpost app load\` before publishing`);
|
|
247
|
+
const values = dotenv.parse(fs.readFileSync(source, 'utf8'));
|
|
248
|
+
const keys = Object.keys(values);
|
|
249
|
+
if (keys.length === 0) throw new Error(`[app] ${source} is empty; nothing to publish`);
|
|
250
|
+
if (fs.existsSync(target) && !context.force)
|
|
251
|
+
throw new Error(`[app] ${target} already exists; re-run with --force to overwrite it`);
|
|
252
|
+
if (context.dryRun) {
|
|
253
|
+
logger.info('[dry-run] app publish would write', { target, keys: keys.length });
|
|
254
|
+
return { target, keys: keys.length };
|
|
255
|
+
}
|
|
256
|
+
writeEnv(target, values);
|
|
257
|
+
logger.info('Deployment environment published', { target, keys: keys.length });
|
|
258
|
+
return { target, keys: keys.length };
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Projects the deployment environment into the cluster as its own Secret, so a workload can
|
|
263
|
+
* inject it with `envFrom` alongside the host configuration.
|
|
264
|
+
* Idempotent — delete-then-apply converges on the current source.
|
|
265
|
+
* @param {object} context - Normalized domain context.
|
|
266
|
+
* @returns {{secret: string, namespace: string, env: string}} What was projected.
|
|
267
|
+
* @memberof UnderpostApp
|
|
268
|
+
*/
|
|
269
|
+
apply(context = {}) {
|
|
270
|
+
context = domainContextFactory(context);
|
|
271
|
+
const deployId = UnderpostApp.API.deployId(context);
|
|
272
|
+
const envFilePath = UnderpostApp.API.envPath(context);
|
|
273
|
+
if (!fs.existsSync(envFilePath)) throw new Error(`[app] deployment environment not found: ${envFilePath}`);
|
|
274
|
+
const secret = appSecretName(deployId, context.env, UnderpostApp.API.instanceId(context));
|
|
275
|
+
// This Secret is consumed only by container workloads, so the OCI overlay is applied
|
|
276
|
+
// unconditionally here — the host projecting it is not the runtime that reads it.
|
|
277
|
+
const { overlay, content } = UnderpostApp.API.ociEnv(context);
|
|
278
|
+
if (context.dryRun) {
|
|
279
|
+
logger.info('[dry-run] app apply would publish the Secret', {
|
|
280
|
+
secret,
|
|
281
|
+
namespace: context.namespace,
|
|
282
|
+
source: envFilePath,
|
|
283
|
+
overlay,
|
|
284
|
+
});
|
|
285
|
+
return { secret, namespace: context.namespace, env: context.env, overlay };
|
|
286
|
+
}
|
|
287
|
+
// The same reserved-key filter the host domain applies: an injected PATH would override
|
|
288
|
+
// the container image's own no matter which Secret carried it.
|
|
289
|
+
const sanitizedEnvPath = `${envFilePath}.secret`;
|
|
290
|
+
fs.writeFileSync(
|
|
291
|
+
sanitizedEnvPath,
|
|
292
|
+
content
|
|
293
|
+
.split('\n')
|
|
294
|
+
.filter((line) => {
|
|
295
|
+
const trimmed = line.trimStart();
|
|
296
|
+
if (!trimmed || trimmed.startsWith('#')) return true;
|
|
297
|
+
const key = line.slice(0, line.indexOf('=')).trim();
|
|
298
|
+
return !key || !isReservedEnvKey(key);
|
|
299
|
+
})
|
|
300
|
+
.join('\n'),
|
|
301
|
+
);
|
|
302
|
+
try {
|
|
303
|
+
shellExec(`kubectl delete secret ${secret} -n ${context.namespace} --ignore-not-found`);
|
|
304
|
+
shellExec(
|
|
305
|
+
`kubectl create secret generic ${secret} --from-env-file=${sanitizedEnvPath} --dry-run=client -o yaml | kubectl apply -f - -n ${context.namespace}`,
|
|
306
|
+
);
|
|
307
|
+
} finally {
|
|
308
|
+
fs.removeSync(sanitizedEnvPath);
|
|
309
|
+
}
|
|
310
|
+
logger.info('Deployment environment applied', {
|
|
311
|
+
secret,
|
|
312
|
+
env: context.env,
|
|
313
|
+
namespace: context.namespace,
|
|
314
|
+
overlay,
|
|
315
|
+
});
|
|
316
|
+
return { secret, namespace: context.namespace, env: context.env, overlay };
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Read-only report: the resolved deployment id, which source is in effect, and whether the
|
|
321
|
+
* cluster projection exists.
|
|
322
|
+
* @param {object} context - Normalized domain context.
|
|
323
|
+
* @returns {object} Report.
|
|
324
|
+
* @memberof UnderpostApp
|
|
325
|
+
*/
|
|
326
|
+
status(context = {}) {
|
|
327
|
+
context = domainContextFactory(context);
|
|
328
|
+
const deployId = UnderpostApp.API.deployId(context);
|
|
329
|
+
const source = UnderpostApp.API.envPath(context);
|
|
330
|
+
const present = fs.existsSync(source);
|
|
331
|
+
const secret = appSecretName(deployId, context.env, UnderpostApp.API.instanceId(context));
|
|
332
|
+
const projected = shellExec(`kubectl get secret ${secret} -n ${context.namespace} -o name`, {
|
|
333
|
+
silent: true,
|
|
334
|
+
stdout: true,
|
|
335
|
+
silentOnError: true,
|
|
336
|
+
disableLog: true,
|
|
337
|
+
});
|
|
338
|
+
const instanceId = UnderpostApp.API.instanceId(context);
|
|
339
|
+
const ociOverlay = instanceId ? '' : deployOciEnvFilePath(deployId, context.env);
|
|
340
|
+
const report = {
|
|
341
|
+
domain: 'app',
|
|
342
|
+
env: context.env,
|
|
343
|
+
namespace: context.namespace,
|
|
344
|
+
deployId,
|
|
345
|
+
instanceId: instanceId || null,
|
|
346
|
+
source,
|
|
347
|
+
sourcePresent: present,
|
|
348
|
+
ociOverlay: ociOverlay && fs.existsSync(ociOverlay) ? ociOverlay : null,
|
|
349
|
+
keys: present ? Object.keys(UnderpostApp.API.read(context)).length : 0,
|
|
350
|
+
clusterSecret: `${projected ?? ''}`.trim() ? secret : null,
|
|
351
|
+
};
|
|
352
|
+
logger.info('app status', report);
|
|
353
|
+
return report;
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Replaces the live projection: deletes the deployment's Secret and re-applies it.
|
|
358
|
+
* @param {object} context - Normalized domain context.
|
|
359
|
+
* @returns {object} The re-applied projection.
|
|
360
|
+
* @memberof UnderpostApp
|
|
361
|
+
*/
|
|
362
|
+
rotate(context = {}) {
|
|
363
|
+
context = domainContextFactory(context);
|
|
364
|
+
const secret = appSecretName(
|
|
365
|
+
UnderpostApp.API.deployId(context),
|
|
366
|
+
context.env,
|
|
367
|
+
UnderpostApp.API.instanceId(context),
|
|
368
|
+
);
|
|
369
|
+
if (context.dryRun) {
|
|
370
|
+
logger.info('[dry-run] app rotate would re-project the Secret', { secret, namespace: context.namespace });
|
|
371
|
+
return { secret, namespace: context.namespace, env: context.env };
|
|
372
|
+
}
|
|
373
|
+
shellExec(`kubectl delete secret ${secret} -n ${context.namespace} --ignore-not-found`);
|
|
374
|
+
return UnderpostApp.API.apply(context);
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Withdraws the deployment environment from the local filesystem: removes the working-tree
|
|
379
|
+
* `.env*` files `loadConf` materializes. `--force` also drops the deployment's cluster Secret.
|
|
380
|
+
* @param {object} context - Normalized domain context.
|
|
381
|
+
* @returns {{removed: Array<string>, removedSecret: string|null}} What was withdrawn.
|
|
382
|
+
* @memberof UnderpostApp
|
|
383
|
+
*/
|
|
384
|
+
clean(context = {}) {
|
|
385
|
+
context = domainContextFactory(context);
|
|
386
|
+
const secret = context.force
|
|
387
|
+
? appSecretName(UnderpostApp.API.deployId(context), context.env, UnderpostApp.API.instanceId(context))
|
|
388
|
+
: null;
|
|
389
|
+
if (context.dryRun) {
|
|
390
|
+
logger.info('[dry-run] app clean would remove the working-tree env files', { secret });
|
|
391
|
+
return { removed: [], removedSecret: secret };
|
|
392
|
+
}
|
|
393
|
+
const removed = cleanDeployEnvFiles();
|
|
394
|
+
if (secret) shellExec(`kubectl delete secret ${secret} -n ${context.namespace} --ignore-not-found`);
|
|
395
|
+
logger.info('Deployment environment withdrawn', { files: removed, secret });
|
|
396
|
+
return { removed, removedSecret: secret };
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export default UnderpostApp;
|
|
402
|
+
export { appSecretName, UnderpostApp };
|
package/src/cli/baremetal.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
|
-
import { getNpmRootPath } from '../server/environment.js';
|
|
9
|
-
import { pbcopy, shellExec } from '../server/process.js';
|
|
10
|
-
import { loggerFactory, loggerMiddleware } from '../server/logger.js';
|
|
8
|
+
import { getNpmRootPath } from '../server/runtime/environment.js';
|
|
9
|
+
import { pbcopy, shellExec } from '../server/runtime/process.js';
|
|
10
|
+
import { loggerFactory, loggerMiddleware } from '../server/ops/logger.js';
|
|
11
11
|
import fs from 'fs-extra';
|
|
12
12
|
import path from 'path';
|
|
13
|
-
import Downloader from '../server/downloader.js';
|
|
13
|
+
import Downloader from '../server/storage/downloader.js';
|
|
14
14
|
import { newInstance, range, s4, timer } from '../client/components/core/CommonJs.js';
|
|
15
15
|
import { spawnSync } from 'child_process';
|
|
16
16
|
import Underpost from '../index.js';
|
|
@@ -97,7 +97,7 @@ class UnderpostBaremetal {
|
|
|
97
97
|
* @param {boolean} [options.worker=false] - Flag to designate the machine as a worker node.
|
|
98
98
|
* @param {string} [options.control=''] - Specifies the control node for the baremetal machine.
|
|
99
99
|
* @param {string} [options.sshKeyDir=''] - Specifies the directory containing SSH keys for the baremetal machine.
|
|
100
|
-
* @param {string} [options.deployId=''] - Specifies the deployment ID
|
|
100
|
+
* @param {string} [options.deployId=''] - Specifies the deployment ID used to resolve the private engine repo cloned onto the node.
|
|
101
101
|
* @param {string} [options.engineRepo=''] - Specifies the custom engine repository URL.
|
|
102
102
|
* @param {string} [options.engineBranch=''] - Specifies the custom engine repository branch.
|
|
103
103
|
* @param {string} [options.enginePrivateRepo=''] - Specifies the custom private engine repository URL.
|
|
@@ -943,7 +943,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
943
943
|
`id root`,
|
|
944
944
|
`ls -la /home/root/.ssh/`,
|
|
945
945
|
`cat /home/root/.ssh/authorized_keys`,
|
|
946
|
-
'
|
|
946
|
+
'cd /home/dd/engine && node bin test unit,infra',
|
|
947
947
|
],
|
|
948
948
|
});
|
|
949
949
|
}
|
|
@@ -1490,7 +1490,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1490
1490
|
if (!joinResult.ok || !joinCommand) {
|
|
1491
1491
|
throw new Error(
|
|
1492
1492
|
`Failed to retrieve kubeadm join command from control-plane ${controlUser}@${controlIp} using key "${keyPath}" (code ${joinResult.code}). ` +
|
|
1493
|
-
`Ensure that key authorizes ${controlUser}@${controlIp} — pass --
|
|
1493
|
+
`Ensure that key authorizes ${controlUser}@${controlIp} — pass --user <user> (key from engine-private/deploy/users/<user>) ` +
|
|
1494
1494
|
`or --ssh-key-dir <dir> to use the key/user the control-plane accepts. stderr: ${joinResult.stderr.slice(-300)}`,
|
|
1495
1495
|
);
|
|
1496
1496
|
}
|
|
@@ -1514,7 +1514,6 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
1516
|
// Secrets needed on the node to clone the private engine-private repo
|
|
1517
|
-
// (engine-private/conf/.../.env.production for `node bin run secret`).
|
|
1518
1517
|
const githubUsername = Underpost.baremetal.readEngineConfig('GITHUB_USERNAME') || 'underpostnet';
|
|
1519
1518
|
const githubEnv = {
|
|
1520
1519
|
GITHUB_TOKEN: Underpost.baremetal.readEngineConfig('GITHUB_TOKEN'),
|
|
@@ -1988,7 +1987,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1988
1987
|
try {
|
|
1989
1988
|
return { machine };
|
|
1990
1989
|
} catch (error) {
|
|
1991
|
-
console.
|
|
1990
|
+
console.error(error);
|
|
1992
1991
|
logger.error(error);
|
|
1993
1992
|
throw new Error(`Failed to create MAAS machine. Output:\n${machine}`);
|
|
1994
1993
|
}
|
|
@@ -2597,11 +2596,10 @@ shell
|
|
|
2597
2596
|
*
|
|
2598
2597
|
* Key-dir precedence:
|
|
2599
2598
|
* 1. `--ssh-key-dir <dir>` (explicit path)
|
|
2600
|
-
* 2.
|
|
2601
|
-
*
|
|
2602
|
-
*
|
|
2603
|
-
* 4.
|
|
2604
|
-
* 5. default `engine-private/deploy`
|
|
2599
|
+
* 2. workflow `sshKeyDir`
|
|
2600
|
+
* 3. a non-root user → `engine-private/deploy/users/<user>`
|
|
2601
|
+
* (the cluster scoped key store `src/cli/ssh.js` writes; no key path needed)
|
|
2602
|
+
* 4. default `engine-private/deploy` (the controller key, i.e. root)
|
|
2605
2603
|
*
|
|
2606
2604
|
* User precedence: `--user` > workflow `user` > `root`. A leading `~` in the
|
|
2607
2605
|
* resolved dir is expanded to the user's home.
|
|
@@ -2615,13 +2613,13 @@ shell
|
|
|
2615
2613
|
resolveSshKeyPaths({ options = {}, workflowsConfig = {}, workflowId = '' } = {}) {
|
|
2616
2614
|
const wf = workflowsConfig?.[workflowId] || {};
|
|
2617
2615
|
const user = options.user || wf.user || 'root';
|
|
2616
|
+
// Kept for the private engine repo naming only; SSH keys are cluster scoped.
|
|
2618
2617
|
const deployId = options.deployId || wf.deployId || '';
|
|
2619
2618
|
|
|
2620
2619
|
let dir;
|
|
2621
2620
|
if (options.sshKeyDir) dir = options.sshKeyDir;
|
|
2622
|
-
else if (options.deployId) dir = `engine-private/conf/${options.deployId}/users/${user}`;
|
|
2623
2621
|
else if (wf.sshKeyDir) dir = wf.sshKeyDir;
|
|
2624
|
-
else if (
|
|
2622
|
+
else if (user !== 'root') dir = path.normalize(Underpost.ssh.userKeyDir(user));
|
|
2625
2623
|
else dir = 'engine-private/deploy';
|
|
2626
2624
|
|
|
2627
2625
|
if (dir.startsWith('~')) dir = path.join(process.env.HOME || '', dir.slice(1));
|
|
@@ -2633,10 +2631,10 @@ shell
|
|
|
2633
2631
|
* @description Resolves the login accounts baked into the deployed OS. Always
|
|
2634
2632
|
* creates TWO admin accounts so a console login is guaranteed:
|
|
2635
2633
|
* 1. the MAAS admin (MAAS_ADMIN_USERNAME / MAAS_ADMIN_PASS) — password login,
|
|
2636
|
-
* 2. the deploy user (`--user`, e.g. admin) — its
|
|
2637
|
-
*
|
|
2638
|
-
* root always gets MAAS_ADMIN_PASS. The deploy user/password come from
|
|
2639
|
-
* `engine-private/conf
|
|
2634
|
+
* 2. the deploy user (`--user`, e.g. admin) — its cluster config password
|
|
2635
|
+
* (or MAAS_ADMIN_PASS), plus the SSH key.
|
|
2636
|
+
* root always gets MAAS_ADMIN_PASS. The deploy user/password come from the
|
|
2637
|
+
* cluster users registry `engine-private/deploy/conf.users.json`.
|
|
2640
2638
|
* @param {object} params
|
|
2641
2639
|
* @param {object} [params.options={}] - CLI options.
|
|
2642
2640
|
* @param {object} [params.workflowsConfig={}] - Loaded workflows config.
|
|
@@ -2645,21 +2643,18 @@ shell
|
|
|
2645
2643
|
* @memberof UnderpostBaremetal
|
|
2646
2644
|
*/
|
|
2647
2645
|
resolveInstallCredentials({ options = {}, workflowsConfig = {}, workflowId = '' } = {}) {
|
|
2648
|
-
const { user
|
|
2646
|
+
const { user } = Underpost.baremetal.resolveSshKeyPaths({ options, workflowsConfig, workflowId });
|
|
2649
2647
|
|
|
2650
2648
|
let confUser = {};
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
confUser = JSON.parse(fs.readFileSync(confPath, 'utf8'))?.users?.[user] || {};
|
|
2656
|
-
} catch (error) {
|
|
2657
|
-
logger.warn(`Failed to parse ${confPath}: ${error.message}`);
|
|
2658
|
-
}
|
|
2659
|
-
} else {
|
|
2660
|
-
logger.warn(`conf.node.json not found at ${confPath}; using MAAS_ADMIN_* defaults`);
|
|
2661
|
-
}
|
|
2649
|
+
try {
|
|
2650
|
+
confUser = Underpost.ssh.findUser(user) || {};
|
|
2651
|
+
} catch (error) {
|
|
2652
|
+
logger.warn(`Failed to parse ${Underpost.ssh.usersConfPath()}: ${error.message}`);
|
|
2662
2653
|
}
|
|
2654
|
+
if (!confUser.user)
|
|
2655
|
+
logger.warn(
|
|
2656
|
+
`User '${user}' is not registered in ${Underpost.ssh.usersConfPath()}; using MAAS_ADMIN_* defaults`,
|
|
2657
|
+
);
|
|
2663
2658
|
|
|
2664
2659
|
const maasPass = process.env.MAAS_ADMIN_PASS || '';
|
|
2665
2660
|
const rootPassword = maasPass;
|
|
@@ -2667,7 +2662,7 @@ shell
|
|
|
2667
2662
|
const adminUsername = process.env.MAAS_ADMIN_USERNAME || 'maas';
|
|
2668
2663
|
const adminPassword = maasPass;
|
|
2669
2664
|
// User 2: the deploy user (only when distinct from root/maas admin).
|
|
2670
|
-
const deployUsername =
|
|
2665
|
+
const deployUsername = user && user !== 'root' && user !== adminUsername ? user : '';
|
|
2671
2666
|
const deployPassword = deployUsername ? confUser.password || maasPass : '';
|
|
2672
2667
|
|
|
2673
2668
|
if (!rootPassword) {
|
|
@@ -2682,14 +2677,14 @@ shell
|
|
|
2682
2677
|
* @method readEngineConfig
|
|
2683
2678
|
* @description Reads an engine config/secret value (e.g. GITHUB_TOKEN) on the
|
|
2684
2679
|
* controller. Prefers the loaded process env, falling back to
|
|
2685
|
-
* `node bin
|
|
2680
|
+
* `node bin host get --plain <key>`.
|
|
2686
2681
|
* @param {string} key - Config/env key name.
|
|
2687
2682
|
* @returns {string} The resolved value, or '' if unset.
|
|
2688
2683
|
* @memberof UnderpostBaremetal
|
|
2689
2684
|
*/
|
|
2690
2685
|
readEngineConfig(key) {
|
|
2691
2686
|
if (process.env[key]) return process.env[key];
|
|
2692
|
-
const out = shellExec(`node bin
|
|
2687
|
+
const out = shellExec(`node bin host get --plain ${key}`, {
|
|
2693
2688
|
stdout: true,
|
|
2694
2689
|
silent: true,
|
|
2695
2690
|
silentOnError: true,
|