cyberia 3.1.3 → 3.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +0 -2
- package/.github/workflows/engine-cyberia.cd.yml +10 -8
- package/.github/workflows/engine-cyberia.ci.yml +12 -29
- package/.github/workflows/ghpkg.ci.yml +4 -4
- package/.github/workflows/npmpkg.ci.yml +28 -11
- package/.github/workflows/publish.ci.yml +21 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
- package/.github/workflows/release.cd.yml +14 -10
- package/CHANGELOG.md +783 -1
- package/CLI-HELP.md +95 -18
- package/Dockerfile +0 -2
- package/README.md +290 -220
- package/bin/build.js +24 -7
- package/bin/cyberia.js +2838 -252
- package/bin/deploy.js +747 -125
- package/bin/file.js +9 -0
- package/bin/index.js +2838 -252
- package/bin/vs.js +1 -1
- package/conf.js +99 -65
- package/deployment.yaml +18 -164
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2559 -5864
- package/hardhat/package.json +14 -23
- package/hardhat/scripts/deployObjectLayerToken.js +1 -1
- package/hardhat/test/ObjectLayerToken.js +4 -2
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
- package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +39 -24
- package/proxy.yaml +7 -79
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +15 -36
- package/src/api/ipfs/ipfs.model.js +47 -47
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +67 -129
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +126 -43
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +11 -27
- package/src/cli/cluster.js +68 -21
- package/src/cli/db.js +753 -825
- package/src/cli/deploy.js +215 -125
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +82 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +74 -3
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +340 -0
- package/src/cli/repository.js +475 -74
- package/src/cli/run.js +582 -43
- package/src/cli/secrets.js +73 -0
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +18 -22
- package/src/client/CyberiaPortal.index.js +19 -24
- package/src/client/Default.index.js +21 -34
- package/src/client/Itemledger.index.js +20 -27
- package/src/client/Underpost.index.js +19 -24
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +43 -64
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +194 -96
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +26 -19
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +43 -43
- package/src/client/components/core/LogOut.js +25 -16
- package/src/client/components/core/Modal.js +462 -179
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -51
- package/src/client/components/core/PanelForm.js +44 -144
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +112 -30
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +9 -7
- package/src/client/components/default/LogOutDefault.js +8 -6
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +9 -7
- package/src/client/components/itemledger/LogOutItemledger.js +8 -6
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +9 -7
- package/src/client/components/underpost/LogOutUnderpost.js +8 -6
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +35 -55
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +6 -6
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +14 -40
- package/src/client/services/object-layer/object-layer.management.js +14 -14
- package/src/client/services/object-layer/object-layer.service.js +39 -24
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +6 -6
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +642 -0
- package/src/index.js +24 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +5 -1
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +17 -5
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +52 -46
- package/src/server/client-build.js +356 -82
- package/src/server/client-formatted.js +140 -57
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +25 -23
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +24 -1
- package/src/server/ipfs-client.js +253 -89
- package/src/server/object-layer.js +150 -114
- package/src/server/peer.js +8 -0
- package/src/server/process.js +13 -27
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +319 -0
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +1164 -0
- package/src/server/semantic-layer-generator.js +211 -542
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +19 -5
- package/src/server/valkey.js +141 -235
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -59
- package/jsdoc.json +0 -59
- package/src/api/object-layer/README.md +0 -347
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- package/src/ws/default/management/default.ws.main.js +0 -8
package/src/cli/deploy.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
buildPortProxyRouter,
|
|
10
10
|
buildProxyRouter,
|
|
11
11
|
Config,
|
|
12
|
+
cronDeployIdResolve,
|
|
12
13
|
deployRangePortFactory,
|
|
13
14
|
getDataDeploy,
|
|
14
15
|
loadConfServerJson,
|
|
@@ -124,30 +125,47 @@ class UnderpostDeploy {
|
|
|
124
125
|
* @param {string} namespace - Kubernetes namespace for the deployment.
|
|
125
126
|
* @param {Array<object>} volumes - Volume configurations for the deployment.
|
|
126
127
|
* @param {Array<string>} cmd - Command to run in the deployment container.
|
|
128
|
+
* @param {boolean} skipFullBuild - Whether to skip the full client bundle build during deployment.
|
|
129
|
+
* @param {boolean} pullBundle - Whether to pull the pre-built client bundle from Cloudinary before starting. Use together with skipFullBuild to skip the local build entirely.
|
|
127
130
|
* @returns {string} - YAML deployment configuration for the specified deployment.
|
|
128
131
|
* @memberof UnderpostDeploy
|
|
129
132
|
*/
|
|
130
|
-
deploymentYamlPartsFactory({
|
|
133
|
+
deploymentYamlPartsFactory({
|
|
134
|
+
deployId,
|
|
135
|
+
env,
|
|
136
|
+
suffix,
|
|
137
|
+
resources,
|
|
138
|
+
replicas,
|
|
139
|
+
image,
|
|
140
|
+
namespace,
|
|
141
|
+
volumes,
|
|
142
|
+
cmd,
|
|
143
|
+
skipFullBuild,
|
|
144
|
+
pullBundle,
|
|
145
|
+
}) {
|
|
131
146
|
if (!cmd)
|
|
132
|
-
cmd =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
cmd =
|
|
148
|
+
pullBundle || skipFullBuild
|
|
149
|
+
? [
|
|
150
|
+
// When pullBundle (or skipFullBuild) is set the container pulls the pre-built client
|
|
151
|
+
// bundle from Cloudinary (push-bundle must have been run on the dev machine beforehand).
|
|
152
|
+
`underpost secret underpost --create-from-env`,
|
|
153
|
+
`underpost start --build --run --pull-bundle --skip-full-build ${deployId} ${env}`,
|
|
154
|
+
]
|
|
155
|
+
: [
|
|
156
|
+
// `npm install -g npm@11.2.0`,
|
|
157
|
+
// `npm install -g underpost`,
|
|
158
|
+
`underpost secret underpost --create-from-env`,
|
|
159
|
+
`underpost start --build --run ${deployId} ${env}`,
|
|
160
|
+
];
|
|
138
161
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
139
|
-
if (!volumes)
|
|
140
|
-
volumes = [
|
|
141
|
-
{
|
|
142
|
-
volumeMountPath: '/etc/config',
|
|
143
|
-
volumeName: 'config-volume',
|
|
144
|
-
configMap: 'underpost-config',
|
|
145
|
-
},
|
|
146
|
-
];
|
|
162
|
+
if (!volumes) volumes = [];
|
|
147
163
|
const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
|
|
148
164
|
? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
|
|
149
165
|
: [];
|
|
150
166
|
volumes = volumes.concat(confVolume);
|
|
167
|
+
// const containerImage = image ? image : `localhost/rockylinux9-underpost:v${packageJson.version}`;
|
|
168
|
+
const containerImage = image ? image : `underpost/underpost-engine:v${packageJson.version}`;
|
|
151
169
|
return `apiVersion: apps/v1
|
|
152
170
|
kind: Deployment
|
|
153
171
|
metadata:
|
|
@@ -155,6 +173,7 @@ metadata:
|
|
|
155
173
|
namespace: ${namespace ? namespace : 'default'}
|
|
156
174
|
labels:
|
|
157
175
|
app: ${deployId}-${env}-${suffix}
|
|
176
|
+
deploy-id: ${deployId}-${env}
|
|
158
177
|
spec:
|
|
159
178
|
replicas: ${replicas}
|
|
160
179
|
selector:
|
|
@@ -164,10 +183,15 @@ spec:
|
|
|
164
183
|
metadata:
|
|
165
184
|
labels:
|
|
166
185
|
app: ${deployId}-${env}-${suffix}
|
|
186
|
+
deploy-id: ${deployId}-${env}
|
|
167
187
|
spec:
|
|
168
188
|
containers:
|
|
169
189
|
- name: ${deployId}-${env}-${suffix}
|
|
170
|
-
image: ${
|
|
190
|
+
image: ${containerImage}
|
|
191
|
+
imagePullPolicy: ${containerImage.startsWith('localhost/') ? 'Never' : 'IfNotPresent'}
|
|
192
|
+
envFrom:
|
|
193
|
+
- secretRef:
|
|
194
|
+
name: underpost-config
|
|
171
195
|
${
|
|
172
196
|
resources
|
|
173
197
|
? ` resources:
|
|
@@ -183,13 +207,17 @@ ${
|
|
|
183
207
|
- /bin/sh
|
|
184
208
|
- -c
|
|
185
209
|
- >
|
|
186
|
-
${cmd.join(
|
|
210
|
+
${cmd.join(' &&\n ')}
|
|
187
211
|
|
|
188
|
-
${
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
212
|
+
${
|
|
213
|
+
volumes.length > 0
|
|
214
|
+
? Underpost.deploy
|
|
215
|
+
.volumeFactory(volumes.map((v) => ((v.version = `${deployId}-${env}-${suffix}`), v)))
|
|
216
|
+
.render.split(`\n`)
|
|
217
|
+
.map((l) => ' ' + l)
|
|
218
|
+
.join(`\n`)
|
|
219
|
+
: ''
|
|
220
|
+
}
|
|
193
221
|
---
|
|
194
222
|
apiVersion: v1
|
|
195
223
|
kind: Service
|
|
@@ -218,6 +246,8 @@ spec:
|
|
|
218
246
|
* @param {string} [options.retryPerTryTimeout] - Retry per-try timeout setting for the deployment.
|
|
219
247
|
* @param {boolean} [options.disableDeploymentProxy] - Whether to disable deployment proxy.
|
|
220
248
|
* @param {string} [options.traffic] - Traffic status for the deployment.
|
|
249
|
+
* @param {boolean} [options.skipFullBuild] - Whether to skip the full client bundle build; forwarded to deploymentYamlPartsFactory to generate a pull-bundle startup command.
|
|
250
|
+
* @param {boolean} [options.pullBundle] - Whether to pull the pre-built client bundle from Cloudinary; forwarded to deploymentYamlPartsFactory. Use together with skipFullBuild.
|
|
221
251
|
* @returns {Promise<void>} - Promise that resolves when the manifest is built.
|
|
222
252
|
* @memberof UnderpostDeploy
|
|
223
253
|
*/
|
|
@@ -254,12 +284,22 @@ ${Underpost.deploy
|
|
|
254
284
|
image,
|
|
255
285
|
namespace: options.namespace,
|
|
256
286
|
cmd: options.cmd ? options.cmd.split(',').map((c) => c.trim()) : undefined,
|
|
287
|
+
skipFullBuild: options.skipFullBuild,
|
|
288
|
+
pullBundle: options.pullBundle,
|
|
257
289
|
})
|
|
258
290
|
.replace('{{ports}}', buildKindPorts(fromPort, toPort))}
|
|
259
291
|
`;
|
|
260
292
|
}
|
|
261
293
|
fs.writeFileSync(`./engine-private/conf/${deployId}/build/${env}/deployment.yaml`, deploymentYamlParts, 'utf8');
|
|
262
294
|
|
|
295
|
+
Underpost.deploy.buildGrpcServiceManifest({
|
|
296
|
+
deployId,
|
|
297
|
+
env,
|
|
298
|
+
confServer,
|
|
299
|
+
namespace: options.namespace,
|
|
300
|
+
traffic: options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'],
|
|
301
|
+
});
|
|
302
|
+
|
|
263
303
|
const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
|
|
264
304
|
? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
|
|
265
305
|
: [];
|
|
@@ -369,6 +409,67 @@ ${Underpost.deploy
|
|
|
369
409
|
}
|
|
370
410
|
}
|
|
371
411
|
},
|
|
412
|
+
/**
|
|
413
|
+
* Builds and writes a gRPC ClusterIP service YAML for a deployment.
|
|
414
|
+
* Scans conf.server.json for gRPC ports and emits grpc-service.yaml under
|
|
415
|
+
* `engine-private/conf/<deployId>/build/<env>/`. The selector always uses the
|
|
416
|
+
* explicit `app: <deployId>-<env>-<traffic>` label to target only the active
|
|
417
|
+
* colour (blue or green).
|
|
418
|
+
* @param {string} deployId - Deployment ID.
|
|
419
|
+
* @param {string} env - Environment ('development' or 'production').
|
|
420
|
+
* @param {object} confServer - Parsed conf.server.json content.
|
|
421
|
+
* @param {string} [namespace='default'] - Kubernetes namespace.
|
|
422
|
+
* @param {string[]} [traffic=['blue']] - Active traffic colour(s) ('blue', 'green', or both).
|
|
423
|
+
* @param {string|null} [host=null] - Specific host to scan for gRPC ports. If null, all hosts are scanned.
|
|
424
|
+
* @returns {string|null} - Path to the written YAML file, or null if no gRPC ports found.
|
|
425
|
+
* @memberof UnderpostDeploy
|
|
426
|
+
*/
|
|
427
|
+
buildGrpcServiceManifest({ deployId, env, confServer, namespace = 'default', traffic = ['blue'], host = null }) {
|
|
428
|
+
const grpcPorts = new Set();
|
|
429
|
+
const hostsToScan = host ? [host] : Object.keys(confServer);
|
|
430
|
+
for (const h of hostsToScan) {
|
|
431
|
+
if (!confServer[h]) continue;
|
|
432
|
+
for (const path of Object.keys(confServer[h])) {
|
|
433
|
+
const grpc = confServer[h][path].grpc;
|
|
434
|
+
if (grpc && grpc.port) grpcPorts.add(parseInt(grpc.port));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (grpcPorts.size === 0) return null;
|
|
438
|
+
const grpcPortsList = [...grpcPorts]
|
|
439
|
+
.map(
|
|
440
|
+
(port) => ` - name: grpc-${port}
|
|
441
|
+
protocol: TCP
|
|
442
|
+
port: ${port}
|
|
443
|
+
targetPort: ${port}`,
|
|
444
|
+
)
|
|
445
|
+
.join('\n');
|
|
446
|
+
let grpcServiceYaml = '';
|
|
447
|
+
for (const color of traffic) {
|
|
448
|
+
const grpcServiceName = `${deployId}-grpc-service-${env}-${color}`;
|
|
449
|
+
const selectorYaml = `app: ${deployId}-${env}-${color}`;
|
|
450
|
+
grpcServiceYaml += `---
|
|
451
|
+
apiVersion: v1
|
|
452
|
+
kind: Service
|
|
453
|
+
metadata:
|
|
454
|
+
name: ${grpcServiceName}
|
|
455
|
+
namespace: ${namespace}
|
|
456
|
+
labels:
|
|
457
|
+
app: ${grpcServiceName}
|
|
458
|
+
spec:
|
|
459
|
+
type: ClusterIP
|
|
460
|
+
selector:
|
|
461
|
+
${selectorYaml}
|
|
462
|
+
ports:
|
|
463
|
+
${grpcPortsList}
|
|
464
|
+
`;
|
|
465
|
+
logger.info(
|
|
466
|
+
`gRPC ClusterIP service YAML written: ${grpcServiceName} (selector: ${selectorYaml}, ports: ${[...grpcPorts].join(', ')})`,
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
const yamlPath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
|
|
470
|
+
fs.writeFileSync(yamlPath, grpcServiceYaml, 'utf8');
|
|
471
|
+
return yamlPath;
|
|
472
|
+
},
|
|
372
473
|
/**
|
|
373
474
|
* Builds a Certificate resource for a host using cert-manager.
|
|
374
475
|
* @param {string} host - Hostname for which the certificate is being built.
|
|
@@ -478,6 +579,13 @@ spec:
|
|
|
478
579
|
* @param {string} [options.kindType] - Type of Kubernetes resource to retrieve information for.
|
|
479
580
|
* @param {number} [options.port] - Port number for exposing the deployment.
|
|
480
581
|
* @param {string} [options.cmd] - Custom initialization command for deploymentYamlPartsFactory (comma-separated commands).
|
|
582
|
+
* @param {number} [options.exposePort] - Local:remote port override when --expose is active (overrides auto-detected service port).
|
|
583
|
+
* @param {boolean} [options.k3s] - Whether to use k3s cluster context.
|
|
584
|
+
* @param {boolean} [options.kubeadm] - Whether to use kubeadm cluster context.
|
|
585
|
+
* @param {boolean} [options.kind] - Whether to use kind cluster context.
|
|
586
|
+
* @param {boolean} [options.gitClean] - Whether to run git clean on volume mount paths before copying.
|
|
587
|
+
* @param {boolean} [options.skipFullBuild] - Whether to skip the full client bundle build; passed through to buildManifest/deploymentYamlPartsFactory.
|
|
588
|
+
* @param {boolean} [options.pullBundle] - Whether to pull the pre-built client bundle from Cloudinary; passed through to buildManifest/deploymentYamlPartsFactory. Use together with skipFullBuild.
|
|
481
589
|
* @returns {Promise<void>} - Promise that resolves when the deployment process is complete.
|
|
482
590
|
* @memberof UnderpostDeploy
|
|
483
591
|
*/
|
|
@@ -515,6 +623,10 @@ spec:
|
|
|
515
623
|
port: 0,
|
|
516
624
|
exposePort: 0,
|
|
517
625
|
cmd: '',
|
|
626
|
+
k3s: false,
|
|
627
|
+
kubeadm: false,
|
|
628
|
+
kind: false,
|
|
629
|
+
gitClean: false,
|
|
518
630
|
},
|
|
519
631
|
) {
|
|
520
632
|
const namespace = options.namespace ? options.namespace : 'default';
|
|
@@ -544,6 +656,8 @@ EOF`);
|
|
|
544
656
|
path: instance.path,
|
|
545
657
|
fromPort: instance.fromPort,
|
|
546
658
|
toPort: instance.toPort,
|
|
659
|
+
fromDebugPort: instance.fromDebugPort,
|
|
660
|
+
toDebugPort: instance.toDebugPort,
|
|
547
661
|
traffic: Underpost.deploy.getCurrentTraffic(_deployId, { namespace, hostTest: instance.host }),
|
|
548
662
|
});
|
|
549
663
|
}
|
|
@@ -553,7 +667,7 @@ EOF`);
|
|
|
553
667
|
env,
|
|
554
668
|
traffic: Underpost.deploy.getCurrentTraffic(deployId, { namespace }),
|
|
555
669
|
router: await Underpost.deploy.routerFactory(deployId, env),
|
|
556
|
-
pods: await Underpost.
|
|
670
|
+
pods: await Underpost.kubectl.get(deployId),
|
|
557
671
|
instances,
|
|
558
672
|
});
|
|
559
673
|
}
|
|
@@ -595,7 +709,7 @@ EOF`);
|
|
|
595
709
|
if (!deployId) continue;
|
|
596
710
|
if (options.expose === true) {
|
|
597
711
|
const kindType = options.kindType ? options.kindType : 'svc';
|
|
598
|
-
const svc = Underpost.
|
|
712
|
+
const svc = Underpost.kubectl.get(deployId, kindType)[0];
|
|
599
713
|
const port = options.exposePort
|
|
600
714
|
? parseInt(options.exposePort)
|
|
601
715
|
: options.port
|
|
@@ -634,6 +748,8 @@ EOF`);
|
|
|
634
748
|
version,
|
|
635
749
|
namespace,
|
|
636
750
|
nodeName: options.node ? options.node : env === 'development' ? 'kind-worker' : os.hostname(),
|
|
751
|
+
clusterContext: options.k3s ? 'k3s' : options.kubeadm ? 'kubeadm' : 'kind',
|
|
752
|
+
gitClean: options.gitClean || false,
|
|
637
753
|
});
|
|
638
754
|
}
|
|
639
755
|
|
|
@@ -652,8 +768,11 @@ EOF`);
|
|
|
652
768
|
: `manifests/deployment/${deployId}-${env}`;
|
|
653
769
|
|
|
654
770
|
if (!options.remove) {
|
|
655
|
-
if (!options.disableUpdateDeployment)
|
|
771
|
+
if (!options.disableUpdateDeployment) {
|
|
656
772
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/deployment.yaml -n ${namespace}`);
|
|
773
|
+
const grpcServicePath = `./${manifestsPath}/grpc-service.yaml`;
|
|
774
|
+
if (fs.existsSync(grpcServicePath)) shellExec(`sudo kubectl apply -f ${grpcServicePath} -n ${namespace}`);
|
|
775
|
+
}
|
|
657
776
|
if (!options.disableUpdateProxy)
|
|
658
777
|
shellExec(`sudo kubectl apply -f ./${manifestsPath}/proxy.yaml -n ${namespace}`);
|
|
659
778
|
|
|
@@ -671,65 +790,6 @@ EOF`);
|
|
|
671
790
|
` + renderHosts,
|
|
672
791
|
);
|
|
673
792
|
},
|
|
674
|
-
/**
|
|
675
|
-
* Retrieves information about a deployment.
|
|
676
|
-
* @param {string} deployId - Deployment ID for which information is being retrieved.
|
|
677
|
-
* @param {string} kindType - Type of Kubernetes resource to retrieve information for (e.g. 'pods').
|
|
678
|
-
* @param {string} namespace - Kubernetes namespace to retrieve information from.
|
|
679
|
-
* @returns {Array<object>} - Array of objects containing information about the deployment.
|
|
680
|
-
* @memberof UnderpostDeploy
|
|
681
|
-
*/
|
|
682
|
-
get(deployId, kindType = 'pods', namespace = '') {
|
|
683
|
-
const raw = shellExec(
|
|
684
|
-
`sudo kubectl get ${kindType}${namespace ? ` -n ${namespace}` : ` --all-namespaces`} -o wide`,
|
|
685
|
-
{
|
|
686
|
-
stdout: true,
|
|
687
|
-
disableLog: true,
|
|
688
|
-
silent: true,
|
|
689
|
-
},
|
|
690
|
-
);
|
|
691
|
-
|
|
692
|
-
const heads = raw
|
|
693
|
-
.split(`\n`)[0]
|
|
694
|
-
.split(' ')
|
|
695
|
-
.filter((_r) => _r.trim());
|
|
696
|
-
|
|
697
|
-
const pods = raw
|
|
698
|
-
.split(`\n`)
|
|
699
|
-
.filter((r) => (deployId ? r.match(deployId) : r.trim() && !r.match('NAME')))
|
|
700
|
-
.map((r) => r.split(' ').filter((_r) => _r.trim()));
|
|
701
|
-
|
|
702
|
-
const result = [];
|
|
703
|
-
|
|
704
|
-
for (const row of pods) {
|
|
705
|
-
const pod = {};
|
|
706
|
-
let index = -1;
|
|
707
|
-
for (const head of heads) {
|
|
708
|
-
index++;
|
|
709
|
-
pod[head] = row[index];
|
|
710
|
-
}
|
|
711
|
-
result.push(pod);
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
return result;
|
|
715
|
-
},
|
|
716
|
-
|
|
717
|
-
/**
|
|
718
|
-
* Checks if a container file exists in a pod.
|
|
719
|
-
* @param {object} options - Options for the check.
|
|
720
|
-
* @param {string} options.podName - Name of the pod to check.
|
|
721
|
-
* @param {string} options.path - Path to the container file to check.
|
|
722
|
-
* @returns {boolean} - True if the container file exists, false otherwise.
|
|
723
|
-
* @memberof UnderpostDeploy
|
|
724
|
-
*/
|
|
725
|
-
existsContainerFile({ podName, path }) {
|
|
726
|
-
const result = shellExec(`kubectl exec ${podName} -- test -f ${path} && echo "true" || echo "false"`, {
|
|
727
|
-
stdout: true,
|
|
728
|
-
disableLog: true,
|
|
729
|
-
silent: true,
|
|
730
|
-
}).trim();
|
|
731
|
-
return result === 'true';
|
|
732
|
-
},
|
|
733
793
|
/**
|
|
734
794
|
* Checks the status of a deployment.
|
|
735
795
|
* @param {string} deployId - Deployment ID for which the status is being checked.
|
|
@@ -742,7 +802,7 @@ EOF`);
|
|
|
742
802
|
*/
|
|
743
803
|
async checkDeploymentReadyStatus(deployId, env, traffic, ignoresNames = [], namespace = 'default') {
|
|
744
804
|
const cmd = `underpost config get container-status`;
|
|
745
|
-
const pods = Underpost.
|
|
805
|
+
const pods = Underpost.kubectl.get(`${deployId}-${env}-${traffic}`, 'pods', namespace);
|
|
746
806
|
const readyPods = [];
|
|
747
807
|
const notReadyPods = [];
|
|
748
808
|
for (const pod of pods) {
|
|
@@ -768,15 +828,17 @@ EOF`);
|
|
|
768
828
|
};
|
|
769
829
|
},
|
|
770
830
|
/**
|
|
771
|
-
* Creates a
|
|
772
|
-
*
|
|
773
|
-
* @param {string}
|
|
831
|
+
* Creates a Kubernetes Secret for a deployment (replaces configMap for secret data).
|
|
832
|
+
* Secrets are mounted as tmpfs (never written to node disk) and support RBAC restrictions.
|
|
833
|
+
* @param {string} env - Environment for which the secret is being created.
|
|
834
|
+
* @param {string} [namespace='default'] - Kubernetes namespace for the secret.
|
|
774
835
|
* @memberof UnderpostDeploy
|
|
775
836
|
*/
|
|
776
837
|
configMap(env, namespace = 'default') {
|
|
777
|
-
|
|
838
|
+
const cronDeployId = cronDeployIdResolve() || 'dd-cron';
|
|
839
|
+
shellExec(`kubectl delete secret underpost-config -n ${namespace} --ignore-not-found`);
|
|
778
840
|
shellExec(
|
|
779
|
-
`kubectl create
|
|
841
|
+
`kubectl create secret generic underpost-config --from-env-file=/home/dd/engine/engine-private/conf/${cronDeployId}/.env.${env} --dry-run=client -o yaml | kubectl apply -f - -n ${namespace}`,
|
|
780
842
|
);
|
|
781
843
|
},
|
|
782
844
|
/**
|
|
@@ -814,6 +876,9 @@ EOF`);
|
|
|
814
876
|
|
|
815
877
|
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml -n ${namespace}`);
|
|
816
878
|
|
|
879
|
+
const grpcServicePath = `./engine-private/conf/${deployId}/build/${env}/grpc-service.yaml`;
|
|
880
|
+
if (fs.existsSync(grpcServicePath)) shellExec(`kubectl apply -f ${grpcServicePath} -n ${namespace}`);
|
|
881
|
+
|
|
817
882
|
Underpost.env.set(`${deployId}-${env}-traffic`, targetTraffic);
|
|
818
883
|
},
|
|
819
884
|
|
|
@@ -829,6 +894,8 @@ EOF`);
|
|
|
829
894
|
* @param {string} options.version - Version of the deployment.
|
|
830
895
|
* @param {string} options.namespace - Kubernetes namespace for the deployment.
|
|
831
896
|
* @param {string} options.nodeName - Node name for the deployment.
|
|
897
|
+
* @param {string} [options.clusterContext='kind'] - Cluster context type ('kind', 'kubeadm', or 'k3s').
|
|
898
|
+
* @param {boolean} [options.gitClean=false] - Whether to run git clean on volumeMountPath before copying.
|
|
832
899
|
* @memberof UnderpostDeploy
|
|
833
900
|
*/
|
|
834
901
|
deployVolume(
|
|
@@ -839,6 +906,8 @@ EOF`);
|
|
|
839
906
|
version: '',
|
|
840
907
|
namespace: '',
|
|
841
908
|
nodeName: '',
|
|
909
|
+
clusterContext: 'kind',
|
|
910
|
+
gitClean: false,
|
|
842
911
|
},
|
|
843
912
|
) {
|
|
844
913
|
if (!volume.claimName) {
|
|
@@ -846,19 +915,26 @@ EOF`);
|
|
|
846
915
|
return;
|
|
847
916
|
}
|
|
848
917
|
const { deployId, env, version, namespace } = options;
|
|
918
|
+
const clusterContext = options.clusterContext || 'kind';
|
|
849
919
|
const pvcId = `${volume.claimName}-${deployId}-${env}-${version}`;
|
|
850
920
|
const pvId = `${volume.claimName.replace('pvc-', 'pv-')}-${deployId}-${env}-${version}`;
|
|
851
921
|
const rootVolumeHostPath = `/home/dd/engine/volume/${pvId}`;
|
|
922
|
+
if (options.gitClean && volume.volumeMountPath) {
|
|
923
|
+
Underpost.repo.clean({ paths: [volume.volumeMountPath] });
|
|
924
|
+
}
|
|
852
925
|
if (options.nodeName) {
|
|
853
926
|
if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
|
|
854
927
|
fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
|
|
855
|
-
} else {
|
|
928
|
+
} else if (clusterContext === 'kind') {
|
|
856
929
|
shellExec(`docker exec -i kind-worker bash -c "mkdir -p ${rootVolumeHostPath}"`);
|
|
857
930
|
// shellExec(`docker cp ${volume.volumeMountPath} kind-worker:${rootVolumeHostPath}`);
|
|
858
931
|
shellExec(`tar -C ${volume.volumeMountPath} -c . | docker cp - kind-worker:${rootVolumeHostPath}`);
|
|
859
932
|
shellExec(
|
|
860
933
|
`docker exec -i kind-worker bash -c "chown -R 1000:1000 ${rootVolumeHostPath}; chmod -R 755 ${rootVolumeHostPath}"`,
|
|
861
934
|
);
|
|
935
|
+
} else {
|
|
936
|
+
if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
|
|
937
|
+
fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
|
|
862
938
|
}
|
|
863
939
|
shellExec(`kubectl delete pvc ${pvcId} -n ${namespace} --ignore-not-found`);
|
|
864
940
|
shellExec(`kubectl delete pv ${pvId} --ignore-not-found`);
|
|
@@ -881,6 +957,8 @@ EOF
|
|
|
881
957
|
* @param {string} volume.volumeType - Type of the volume (e.g. 'Directory').
|
|
882
958
|
* @param {string|null} volume.claimName - Name of the persistent volume claim (if applicable).
|
|
883
959
|
* @param {string|null} volume.configMap - Name of the config map (if applicable).
|
|
960
|
+
* @param {string|null} volume.secret - Name of the Kubernetes Secret (if applicable). Mounts as readOnly.
|
|
961
|
+
* @param {boolean} [volume.emptyDir=false] - If true, uses an emptyDir volume (writable tmpfs).
|
|
884
962
|
* @returns {object} - Object containing the rendered volume mounts and volumes.
|
|
885
963
|
* @memberof UnderpostDeploy
|
|
886
964
|
*/
|
|
@@ -902,7 +980,17 @@ EOF
|
|
|
902
980
|
let _volumes = `
|
|
903
981
|
volumes:`;
|
|
904
982
|
volumes.map((volumeData) => {
|
|
905
|
-
let {
|
|
983
|
+
let {
|
|
984
|
+
volumeName,
|
|
985
|
+
volumeMountPath,
|
|
986
|
+
volumeHostPath,
|
|
987
|
+
volumeType,
|
|
988
|
+
claimName,
|
|
989
|
+
configMap,
|
|
990
|
+
secret,
|
|
991
|
+
emptyDir,
|
|
992
|
+
version,
|
|
993
|
+
} = volumeData;
|
|
906
994
|
if (version) {
|
|
907
995
|
volumeName = `${volumeName}-${version}`;
|
|
908
996
|
claimName = claimName ? `${claimName}-${version}` : null;
|
|
@@ -910,18 +998,23 @@ EOF
|
|
|
910
998
|
_volumeMounts += `
|
|
911
999
|
- name: ${volumeName}
|
|
912
1000
|
mountPath: ${volumeMountPath}
|
|
913
|
-
`;
|
|
1001
|
+
${secret ? ` readOnly: true\n` : ''}`;
|
|
914
1002
|
|
|
915
1003
|
_volumes += `
|
|
916
1004
|
- name: ${volumeName}
|
|
917
1005
|
${
|
|
918
|
-
|
|
919
|
-
? `
|
|
1006
|
+
emptyDir
|
|
1007
|
+
? ` emptyDir: {}`
|
|
1008
|
+
: secret
|
|
1009
|
+
? ` secret:
|
|
1010
|
+
secretName: ${secret}`
|
|
1011
|
+
: configMap
|
|
1012
|
+
? ` configMap:
|
|
920
1013
|
name: ${configMap}`
|
|
921
|
-
|
|
922
|
-
|
|
1014
|
+
: claimName
|
|
1015
|
+
? ` persistentVolumeClaim:
|
|
923
1016
|
claimName: ${claimName}`
|
|
924
|
-
|
|
1017
|
+
: ` hostPath:
|
|
925
1018
|
path: ${volumeHostPath}
|
|
926
1019
|
type: ${volumeType}
|
|
927
1020
|
`
|
|
@@ -1034,14 +1127,13 @@ ${renderHosts}`,
|
|
|
1034
1127
|
* @param {string} targetTraffic - Target traffic status for the deployment.
|
|
1035
1128
|
* @param {Array<string>} ignorePods - List of pod names to ignore.
|
|
1036
1129
|
* @param {string} [namespace='default'] - Kubernetes namespace for the deployment.
|
|
1037
|
-
* @param {string} [outLogType=''] - Type of log output.
|
|
1038
1130
|
* @returns {object} - Object containing the ready status of the deployment.
|
|
1039
1131
|
* @memberof UnderpostDeploy
|
|
1040
1132
|
*/
|
|
1041
|
-
async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = [], namespace = 'default'
|
|
1133
|
+
async monitorReadyRunner(deployId, env, targetTraffic, ignorePods = [], namespace = 'default') {
|
|
1042
1134
|
let checkStatusIteration = 0;
|
|
1043
1135
|
const checkStatusIterationMsDelay = 1000;
|
|
1044
|
-
const maxIterations =
|
|
1136
|
+
const maxIterations = 3000;
|
|
1045
1137
|
const deploymentId = `${deployId}-${env}-${targetTraffic}`;
|
|
1046
1138
|
const iteratorTag = `[${deploymentId}]`;
|
|
1047
1139
|
logger.info('Deployment init', { deployId, env, targetTraffic, checkStatusIterationMsDelay, namespace });
|
|
@@ -1076,32 +1168,30 @@ ${renderHosts}`,
|
|
|
1076
1168
|
}
|
|
1077
1169
|
}
|
|
1078
1170
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
const { NAME, out } = pod;
|
|
1171
|
+
{
|
|
1172
|
+
let indexOf = -1;
|
|
1173
|
+
for (const pod of result.notReadyPods) {
|
|
1174
|
+
indexOf++;
|
|
1175
|
+
const { NAME, out } = pod;
|
|
1085
1176
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1177
|
+
if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match(deploymentId))
|
|
1178
|
+
lastMsg[NAME] = 'Starting deployment';
|
|
1179
|
+
// else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('underpost'))
|
|
1180
|
+
// lastMsg[NAME] = 'Installing underpost cli';
|
|
1181
|
+
else if (out.match('not') && out.match('found') && checkStatusIteration <= 20 && out.match('task'))
|
|
1182
|
+
lastMsg[NAME] = 'Initializing setup task';
|
|
1183
|
+
else if (out.match('Empty environment variables')) lastMsg[NAME] = 'Setup environment';
|
|
1184
|
+
else if (out.match(`${deployId}-${env}-build-deployment`)) lastMsg[NAME] = 'Building apps/services';
|
|
1185
|
+
else if (out.match(`${deployId}-${env}-initializing-deployment`))
|
|
1186
|
+
lastMsg[NAME] = 'Initializing apps/services';
|
|
1187
|
+
else if (!lastMsg[NAME]) lastMsg[NAME] = `Waiting for status`;
|
|
1097
1188
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
}
|
|
1189
|
+
console.log(
|
|
1190
|
+
'Target pod:',
|
|
1191
|
+
NAME[NAME.match('green') ? 'bgGreen' : 'bgBlue'].bold.black,
|
|
1192
|
+
'| Status:',
|
|
1193
|
+
lastMsg[NAME].bold.magenta,
|
|
1194
|
+
);
|
|
1105
1195
|
}
|
|
1106
1196
|
}
|
|
1107
1197
|
await timer(checkStatusIterationMsDelay);
|
package/src/cli/env.js
CHANGED
|
@@ -12,6 +12,19 @@ import { pbcopy } from '../server/process.js';
|
|
|
12
12
|
|
|
13
13
|
const logger = loggerFactory(import.meta);
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Guards an env file path against stale directory artifacts.
|
|
17
|
+
* Removes the path if it exists as a directory (e.g. `.env/` created by a previous EISDIR bug).
|
|
18
|
+
* @param {string} envPath - The path to the environment file.
|
|
19
|
+
* @memberof UnderpostEnv
|
|
20
|
+
*/
|
|
21
|
+
const guardEnvPath = (envPath) => {
|
|
22
|
+
if (fs.existsSync(envPath) && !fs.statSync(envPath).isFile()) {
|
|
23
|
+
logger.warn(`Removing stale directory at env path: ${envPath}`);
|
|
24
|
+
fs.removeSync(envPath);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
29
|
* @class UnderpostRootEnv
|
|
17
30
|
* @description Manages the environment variables of the underpost root.
|
|
@@ -31,6 +44,7 @@ class UnderpostRootEnv {
|
|
|
31
44
|
*/
|
|
32
45
|
set(key, value, options = { deployId: '', build: false }) {
|
|
33
46
|
const _set = (envPath, key, value) => {
|
|
47
|
+
guardEnvPath(envPath);
|
|
34
48
|
let env = {};
|
|
35
49
|
if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
36
50
|
env[key] = value;
|
|
@@ -48,6 +62,7 @@ class UnderpostRootEnv {
|
|
|
48
62
|
return;
|
|
49
63
|
}
|
|
50
64
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
65
|
+
fs.ensureDirSync(exeRootPath);
|
|
51
66
|
const envPath = `${exeRootPath}/.env`;
|
|
52
67
|
_set(envPath, key, value);
|
|
53
68
|
},
|
|
@@ -60,6 +75,7 @@ class UnderpostRootEnv {
|
|
|
60
75
|
delete(key) {
|
|
61
76
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
62
77
|
const envPath = `${exeRootPath}/.env`;
|
|
78
|
+
guardEnvPath(envPath);
|
|
63
79
|
let env = {};
|
|
64
80
|
if (fs.existsSync(envPath)) env = dotenv.parse(fs.readFileSync(envPath, 'utf8'));
|
|
65
81
|
delete env[key];
|
|
@@ -101,6 +117,7 @@ class UnderpostRootEnv {
|
|
|
101
117
|
list(key, value, options = {}) {
|
|
102
118
|
const exeRootPath = `${getNpmRootPath()}/underpost`;
|
|
103
119
|
const envPath = `${exeRootPath}/.env`;
|
|
120
|
+
guardEnvPath(envPath);
|
|
104
121
|
if (!fs.existsSync(envPath)) {
|
|
105
122
|
logger.warn(`Empty environment variables`);
|
|
106
123
|
return {};
|
|
@@ -136,7 +153,19 @@ class UnderpostRootEnv {
|
|
|
136
153
|
const envPath = `${exeRootPath}/.env`;
|
|
137
154
|
fs.removeSync(envPath);
|
|
138
155
|
},
|
|
156
|
+
/**
|
|
157
|
+
* @method isInsideContainer
|
|
158
|
+
* @description Detects whether the current process is running inside a container.
|
|
159
|
+
* Checks for Kubernetes service injection or Docker's .dockerenv marker.
|
|
160
|
+
* @returns {boolean} True if running inside a container.
|
|
161
|
+
* @memberof UnderpostEnv
|
|
162
|
+
*/
|
|
163
|
+
isInsideContainer() {
|
|
164
|
+
return !!process.env.KUBERNETES_SERVICE_HOST || fs.existsSync('/.dockerenv');
|
|
165
|
+
},
|
|
139
166
|
};
|
|
140
167
|
}
|
|
141
168
|
|
|
142
169
|
export default UnderpostRootEnv;
|
|
170
|
+
|
|
171
|
+
export { guardEnvPath };
|