@underpostnet/cyberia 3.3.0 → 3.3.73
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/.github/workflows/coverall.cyberia.ci.yml +34 -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/pwa-microservices-template-test.ci.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -0
- package/.prettierignore +1 -0
- package/AGENTS.md +47 -0
- package/CHANGELOG.md +565 -2510
- package/CLI-HELP.md +306 -147
- package/Dockerfile +25 -9
- package/Dockerfile.dev +25 -9
- package/Dockerfile.test +4 -4
- package/README.md +21 -1
- package/bin/build.js +66 -41
- package/bin/build.template.js +8 -3
- package/bin/cyberia.js +308 -91
- package/bin/deploy.js +18 -104
- package/bin/index.js +308 -91
- package/conf.js +91 -4
- package/deploy/cyberia-client/deploy.sh +47 -0
- package/deploy/cyberia-client/package.sh +18 -0
- package/deploy/cyberia-client/state.sh +14 -0
- package/deploy/cyberia-server/deploy.sh +47 -0
- package/deploy/cyberia-server/package.sh +18 -0
- package/deploy/cyberia-server/state.sh +14 -0
- package/deploy/dd-cyberia/deploy.sh +6 -26
- package/deploy/dd-cyberia/init.sh +35 -43
- package/deploy/dd-cyberia/package.sh +17 -0
- package/deploy/dd-cyberia/state.sh +14 -0
- package/deploy/dd-cyberia/sync-deploy.sh +92 -170
- package/deploy/lib/github-actions-logging.sh +594 -0
- package/deploy/lib/host.sh +185 -0
- package/deploy/lib/state.sh +62 -0
- package/deploy/pwa-microservices-template/deploy.sh +12 -39
- package/deploy/release/deploy.sh +9 -39
- package/deployment.yaml +7 -2
- package/docker-compose.yml +7 -7
- 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/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 +83 -10
- 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 +3 -3
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +1 -1
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +2 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +2 -2
- 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 +1 -1
- package/src/api/cyberia-action/cyberia-action.service.js +2 -2
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -1
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +1 -1
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
- 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.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.service.js +2 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +2 -2
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +466 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +8 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +1 -1
- package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -1
- package/src/api/cyberia-instance/cyberia-instance.router.js +2 -2
- package/src/api/cyberia-instance/cyberia-instance.service.js +2 -2
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +2 -2
- 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 +2 -2
- package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.service.js +2 -2
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.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 +0 -26
- package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
- 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.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.router.js +2 -2
- package/src/api/object-layer/object-layer.service.js +3 -3
- 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 +391 -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 +184 -82
- package/src/cli/db.js +120 -68
- package/src/cli/deploy.js +153 -71
- 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.js +3 -3
- package/src/cli/host.js +672 -0
- package/src/cli/image.js +4 -6
- package/src/cli/index.js +322 -142
- 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 +558 -363
- package/src/cli/run.js +331 -650
- 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 +199 -125
- package/src/cli/vultr.js +61 -21
- package/src/cli/wireguard.js +1111 -306
- package/src/client/components/core/CalendarCore.js +53 -96
- package/src/client/components/core/Docs.js +258 -211
- package/src/client/components/core/FileExplorer.js +0 -21
- 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-portal/AppShellCyberiaPortal.js +2 -1
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
- 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/CYBERIA-CLI.md +32 -5
- package/src/client/public/cyberia-docs/CYBERIA.md +21 -1
- 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/WHITE-PAPER.md +1 -1
- 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/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 +61 -46
- package/src/client-builder/client-build-live.js +2 -2
- package/src/client-builder/client-build.js +38 -30
- 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/MongooseDB.js +7 -8
- package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
- package/src/grpc/cyberia/grpc-server.js +1 -1
- 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 +1 -1
- package/src/projects/cyberia/besu-genesis-generator.js +3 -3
- package/src/projects/cyberia/catalog-cyberia.js +53 -10
- package/src/projects/cyberia/gemini-client.js +1 -1
- package/src/projects/cyberia/generate-saga.js +1 -1
- package/src/projects/cyberia/hot-reload-trigger.js +1 -1
- package/src/projects/cyberia/instance-data.js +1 -1
- package/src/projects/cyberia/ipfs-client.js +4 -4
- package/src/projects/cyberia/map-preview-generator.js +1 -1
- package/src/projects/cyberia/object-layer.js +1 -1
- package/src/projects/cyberia/semantic-layer-generator.js +1 -1
- package/src/projects/underpost/catalog-underpost.js +9 -1
- package/src/proxy.js +4 -7
- package/src/runtime/cyberia-client/Dockerfile +9 -4
- package/src/runtime/cyberia-client/Dockerfile.dev +8 -2
- package/src/runtime/cyberia-server/Dockerfile +9 -4
- package/src/runtime/cyberia-server/Dockerfile.dev +8 -2
- package/src/runtime/engine-cyberia/Dockerfile +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.test +4 -4
- package/src/runtime/engine-cyberia/docker-compose.yml +7 -7
- 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 +117 -0
- package/src/server/build/execution.js +402 -0
- package/src/server/build/package.js +465 -0
- package/src/server/build/testing.js +528 -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} +3 -3
- 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} +108 -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} +513 -422
- 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} +1 -1
- package/src/server/{downloader.js → storage/downloader.js} +2 -2
- package/src/server/storage/repository.js +68 -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/cyberia-cli-plain-reads.test.js +30 -0
- package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +1 -1
- package/test/integration/app/cyberia/cyberia-load.test.js +467 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +253 -0
- package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -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 +1163 -0
- package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +609 -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/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 +334 -0
- package/test/unit/conf-loading.test.js +303 -0
- package/test/unit/conf-resolution.test.js +979 -0
- package/test/unit/coverage-artifact.test.js +130 -0
- package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
- package/test/unit/deploy-env-resolution.test.js +38 -0
- package/test/unit/deploy-log-table.test.js +447 -0
- package/test/unit/execution-profiles.test.js +219 -0
- package/test/unit/fleet-sync-source.test.js +149 -0
- package/test/unit/logger-redaction.test.js +112 -0
- package/test/unit/package.test.js +403 -0
- package/test/unit/prepare-host.test.js +299 -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 +193 -0
- package/vitest.config.js +58 -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/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/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/environment.js +0 -98
package/src/cli/state.js
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State domain: the runtime monitoring / telemetry layer.
|
|
3
|
+
*
|
|
4
|
+
* An agent that observes one workload's live container execution state, health indicators and
|
|
5
|
+
* performance metrics, and exports them off-cluster. Its base module is
|
|
6
|
+
* {@link module:src/server/runtime/runtime-status.js}, which defines the observation contract;
|
|
7
|
+
* this domain is the operator surface over it.
|
|
8
|
+
*
|
|
9
|
+
* Backed by its own store file, never the host configuration store. The two have different
|
|
10
|
+
* lifetimes and different owners: host configuration is provisioned onto a node and survives,
|
|
11
|
+
* while this is per-container and resets with the container. Sharing one file meant a host
|
|
12
|
+
* operation could erase a workload's status, and a status write could outlive the workload that
|
|
13
|
+
* produced it.
|
|
14
|
+
*
|
|
15
|
+
* The domain has **no durable source**, and that is what makes it the fourth domain rather than
|
|
16
|
+
* a variation on the other three. An observation is only ever true of a running container, so:
|
|
17
|
+
* - `load` collects from the live workload rather than from a file,
|
|
18
|
+
* - `publish` exports the collection off-cluster rather than writing a source back,
|
|
19
|
+
* - `apply` stamps a contract phase into the live workload.
|
|
20
|
+
* That asymmetry is deliberate and is the whole of this domain.
|
|
21
|
+
*
|
|
22
|
+
* Implements the canonical domain action set; see {@link UnderpostDomains.DOMAIN_ACTIONS}.
|
|
23
|
+
* @module src/cli/state.js
|
|
24
|
+
* @namespace UnderpostState
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import fs from 'fs-extra';
|
|
28
|
+
|
|
29
|
+
import { domainContextFactory } from './domains.js';
|
|
30
|
+
import { dotenvStoreFactory } from './dotenv-store.js';
|
|
31
|
+
import { getUnderpostRootPath, isOciRuntime } from '../server/runtime/environment.js';
|
|
32
|
+
import { loggerFactory } from '../server/ops/logger.js';
|
|
33
|
+
import {
|
|
34
|
+
CONTAINER_STATUS_KEY,
|
|
35
|
+
containerStatusValue,
|
|
36
|
+
deployStatusPort,
|
|
37
|
+
normalizeContainerStatus,
|
|
38
|
+
RUNTIME_STATUS,
|
|
39
|
+
runtimeTelemetryPayload,
|
|
40
|
+
setRuntimeStatus,
|
|
41
|
+
} from '../server/runtime/runtime-status.js';
|
|
42
|
+
import Underpost from '../index.js';
|
|
43
|
+
|
|
44
|
+
const logger = loggerFactory(import.meta);
|
|
45
|
+
|
|
46
|
+
const store = dotenvStoreFactory({
|
|
47
|
+
path: () => `${getUnderpostRootPath()}/.state`,
|
|
48
|
+
label: 'container state',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The workload this invocation observes: `<deployId>[-<instanceId>]-<env>`, the same name every
|
|
53
|
+
* other object of that workload is prefixed with.
|
|
54
|
+
* @param {object} context - Normalized domain context.
|
|
55
|
+
* @returns {string} Workload id.
|
|
56
|
+
* @memberof UnderpostState
|
|
57
|
+
*/
|
|
58
|
+
const deployIdOf = (context = {}) =>
|
|
59
|
+
`${context.args?.['deploy-id'] ?? ''}`.trim() || `${process.env.DEPLOY_ID || ''}`.trim();
|
|
60
|
+
|
|
61
|
+
const workloadId = (context = {}) =>
|
|
62
|
+
[deployIdOf(context), `${context.args?.['instance-id'] ?? ''}`.trim()].filter(Boolean).join('-');
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Whether this process is reporting into a GitHub Actions job.
|
|
66
|
+
*
|
|
67
|
+
* `GITHUB_ACTIONS` exists on a runner but is not carried across the SSH hop a remote deploy
|
|
68
|
+
* runs over, so `RUN_QUIET_CI` — which the deploy workflows export explicitly — is what actually
|
|
69
|
+
* marks the far side. Both are honoured, and `deploy/lib/github-actions-logging.sh` reads the same pair.
|
|
70
|
+
* @returns {boolean} True when workflow commands will be interpreted.
|
|
71
|
+
* @memberof UnderpostState
|
|
72
|
+
*/
|
|
73
|
+
const inGithubActions = () => Boolean(process.env.GITHUB_ACTIONS || process.env.RUN_QUIET_CI);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Renders one observation as GitHub Actions workflow commands on stdout.
|
|
77
|
+
*
|
|
78
|
+
* stdout is the only transport that survives the SSH hop: `$GITHUB_OUTPUT` and
|
|
79
|
+
* `$GITHUB_STEP_SUMMARY` are files on the runner, so they are written too when they exist —
|
|
80
|
+
* a direct runner invocation — but never relied on.
|
|
81
|
+
* @param {object} observation - Telemetry observation.
|
|
82
|
+
* @memberof UnderpostState
|
|
83
|
+
*/
|
|
84
|
+
const exportToGithubActions = (observation) => {
|
|
85
|
+
const { workload, status, ready, phase } = observation;
|
|
86
|
+
const summary =
|
|
87
|
+
`${workload || 'workload'} | status=${status ?? 'unknown'} | ready=${ready} | ` +
|
|
88
|
+
`uptime=${observation.metrics?.uptimeSeconds ?? '?'}s | rss=${Math.round(
|
|
89
|
+
(observation.metrics?.rssBytes ?? 0) / 1048576,
|
|
90
|
+
)}MiB`;
|
|
91
|
+
// A fatal phase is an annotation the job surfaces, not a line in a log nobody opens.
|
|
92
|
+
console.log(`::${phase === RUNTIME_STATUS.ERROR ? 'error' : 'notice'} title=underpost state::${summary}`);
|
|
93
|
+
console.log(`::group::underpost state ${workload || ''}`.trimEnd());
|
|
94
|
+
console.log(JSON.stringify(observation, null, 2));
|
|
95
|
+
console.log('::endgroup::');
|
|
96
|
+
const appendFile = (variable, content) => {
|
|
97
|
+
const target = process.env[variable];
|
|
98
|
+
if (!target) return;
|
|
99
|
+
try {
|
|
100
|
+
fs.appendFileSync(target, content);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
logger.warn(`[state] could not write ${variable}`, error?.message ?? error);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
appendFile('GITHUB_OUTPUT', `status=${status ?? ''}\nready=${ready}\nworkload=${workload ?? ''}\n`);
|
|
106
|
+
appendFile('GITHUB_STEP_SUMMARY', `### underpost state\n\n\`\`\`\n${summary}\n\`\`\`\n`);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @class UnderpostState
|
|
111
|
+
* @description Runtime monitoring / telemetry domain, and key-level access to its store.
|
|
112
|
+
* @memberof UnderpostState
|
|
113
|
+
*/
|
|
114
|
+
class UnderpostState {
|
|
115
|
+
static API = {
|
|
116
|
+
...store,
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Whether this process runs inside a container, by Kubernetes service injection or Docker's
|
|
120
|
+
* marker file. Kept on this class because every caller reaches it through the state domain;
|
|
121
|
+
* the detection itself is {@link ServerEnvironment.isOciRuntime}, shared with the OCI env
|
|
122
|
+
* overlay so both agree on what "inside a container" means.
|
|
123
|
+
* @returns {boolean} True when running inside a container.
|
|
124
|
+
* @memberof UnderpostState
|
|
125
|
+
*/
|
|
126
|
+
isInsideContainer() {
|
|
127
|
+
return isOciRuntime();
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The current observation: execution state, health indicators and performance metrics.
|
|
132
|
+
*
|
|
133
|
+
* In-pod this is measured directly. On a node it is collected from the workload's pods over
|
|
134
|
+
* the monitor's own exec transport, so there is one implementation of "read a pod's status"
|
|
135
|
+
* and the agent can never disagree with the monitor that gates the rollout.
|
|
136
|
+
* @param {object} [context] - Normalized domain context.
|
|
137
|
+
* @returns {object} Telemetry observation.
|
|
138
|
+
* @memberof UnderpostState
|
|
139
|
+
*/
|
|
140
|
+
observe(context = {}) {
|
|
141
|
+
const workload = workloadId(context);
|
|
142
|
+
const local = runtimeTelemetryPayload();
|
|
143
|
+
if (UnderpostState.API.isInsideContainer() || !workload)
|
|
144
|
+
return { workload: workload || local.deployId, phase: local.status, ...local, pods: null };
|
|
145
|
+
const pods = Underpost.kubectl
|
|
146
|
+
.get(`${workload}-${context.env}`, 'pods', context.namespace)
|
|
147
|
+
.map((pod) => pod.NAME)
|
|
148
|
+
.filter(Boolean);
|
|
149
|
+
// Status gates the rollout and must stay total; telemetry adds the fields that exist only
|
|
150
|
+
// where the process is measured. A pod that cannot answer the second keeps the first.
|
|
151
|
+
const internalPort = deployStatusPort(deployIdOf(context), context.env);
|
|
152
|
+
const readings = pods.map((pod) => {
|
|
153
|
+
const status = Underpost.monitor.readRuntimeStatusViaExec(pod, context.namespace);
|
|
154
|
+
const telemetry = Underpost.monitor.readRuntimeTelemetryViaExec(pod, context.namespace, internalPort);
|
|
155
|
+
return {
|
|
156
|
+
pod,
|
|
157
|
+
...status,
|
|
158
|
+
health: telemetry.ok ? (telemetry.telemetry?.health ?? null) : null,
|
|
159
|
+
metrics: telemetry.ok ? (telemetry.telemetry?.metrics ?? null) : null,
|
|
160
|
+
telemetryError: telemetry.ok ? undefined : telemetry.transportError,
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
// The workload's phase is its worst reading: one pod latched `error` is the deployment's
|
|
164
|
+
// state, not an outlier to be averaged away.
|
|
165
|
+
const statuses = readings.filter((reading) => reading.ok).map((reading) => reading.status);
|
|
166
|
+
const phase = statuses.includes(RUNTIME_STATUS.ERROR)
|
|
167
|
+
? RUNTIME_STATUS.ERROR
|
|
168
|
+
: statuses.every((status) => status === RUNTIME_STATUS.RUNNING) && statuses.length > 0
|
|
169
|
+
? RUNTIME_STATUS.RUNNING
|
|
170
|
+
: statuses[0];
|
|
171
|
+
return {
|
|
172
|
+
workload,
|
|
173
|
+
env: context.env,
|
|
174
|
+
namespace: context.namespace,
|
|
175
|
+
status: phase ?? null,
|
|
176
|
+
phase: phase ?? null,
|
|
177
|
+
ready: phase === RUNTIME_STATUS.RUNNING,
|
|
178
|
+
pods: readings,
|
|
179
|
+
metrics: { pods: readings.length, reporting: statuses.length },
|
|
180
|
+
observedAt: new Date().toISOString(),
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
// ── canonical domain actions ────────────────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Renders an observation as a fixed-width table, one row per pod.
|
|
188
|
+
*
|
|
189
|
+
* The shape an operator actually watches: JSON is the export format, but a rollout is read
|
|
190
|
+
* by scanning columns. Absent metrics print as `-` rather than collapsing the row, so a pod
|
|
191
|
+
* that answers only the status read still occupies its line.
|
|
192
|
+
* @param {object} observation - The observation to render.
|
|
193
|
+
* @returns {string} The rendered table.
|
|
194
|
+
* @memberof UnderpostState
|
|
195
|
+
*/
|
|
196
|
+
table(observation = {}, refresh = '') {
|
|
197
|
+
const mib = (bytes) => (typeof bytes === 'number' ? `${Math.round(bytes / 1048576)}Mi` : '-');
|
|
198
|
+
const columns = [
|
|
199
|
+
['POD', 42],
|
|
200
|
+
['PHASE', 26],
|
|
201
|
+
['READY', 6],
|
|
202
|
+
['UPTIME', 8],
|
|
203
|
+
['RSS', 9],
|
|
204
|
+
['HEAP', 9],
|
|
205
|
+
['CPU', 10],
|
|
206
|
+
['LOAD', 6],
|
|
207
|
+
];
|
|
208
|
+
const pad = (value, width) => `${value ?? '-'}`.slice(0, width).padEnd(width);
|
|
209
|
+
const line = (cells) => `| ${cells.map(([v, w]) => pad(v, w)).join(' | ')} |`;
|
|
210
|
+
const rows = (observation.pods ?? []).map((reading) =>
|
|
211
|
+
line([
|
|
212
|
+
[reading.pod, 42],
|
|
213
|
+
[reading.status ?? reading.transportError ?? '-', 26],
|
|
214
|
+
[reading.health ? (reading.health.ready ? 'yes' : 'no') : '-', 6],
|
|
215
|
+
[reading.metrics ? `${reading.metrics.uptimeSeconds}s` : '-', 8],
|
|
216
|
+
[mib(reading.metrics?.rssBytes), 9],
|
|
217
|
+
[mib(reading.metrics?.heapUsedBytes), 9],
|
|
218
|
+
[reading.metrics ? `${Math.round((reading.metrics.cpuUserMicros ?? 0) / 1000)}ms` : '-', 10],
|
|
219
|
+
[reading.metrics ? `${reading.metrics.loadAverage1m?.toFixed?.(2) ?? '-'}` : '-', 6],
|
|
220
|
+
]),
|
|
221
|
+
);
|
|
222
|
+
const header = line(columns.map(([name, width]) => [name, width]));
|
|
223
|
+
const rule = `|${columns.map(([, width]) => '-'.repeat(width + 2)).join('|')}|`;
|
|
224
|
+
const clock = new Date().toTimeString().slice(0, 8);
|
|
225
|
+
const title = `Runtime state ${observation.workload ?? 'workload'}${
|
|
226
|
+
refresh ? ` (refresh #${refresh}, ${clock})` : ''
|
|
227
|
+
} | phase=${observation.phase ?? '-'} | pods=${observation.metrics?.pods ?? (observation.pods ?? []).length}`;
|
|
228
|
+
return [title, header, rule, ...(rows.length > 0 ? rows : [line([['(no pods)', 42]])])].join('\n');
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Onboards the agent: confirms the state store is writable, then takes a first observation.
|
|
233
|
+
* Idempotent — repeating it re-observes rather than re-provisioning.
|
|
234
|
+
* @param {object} context - Normalized domain context.
|
|
235
|
+
* @returns {{store: string, workload: string, status: string|null}} What was onboarded.
|
|
236
|
+
* @memberof UnderpostState
|
|
237
|
+
*/
|
|
238
|
+
setup(context = {}) {
|
|
239
|
+
context = domainContextFactory(context);
|
|
240
|
+
const storePath = store.path();
|
|
241
|
+
if (context.dryRun) {
|
|
242
|
+
logger.info('[dry-run] state setup would provision the container state store', { store: storePath });
|
|
243
|
+
return { store: storePath, workload: workloadId(context), status: null };
|
|
244
|
+
}
|
|
245
|
+
fs.ensureFileSync(storePath);
|
|
246
|
+
const { status } = UnderpostState.API.load(context);
|
|
247
|
+
return { store: storePath, workload: workloadId(context), status };
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Collects the live observation into this node's state store.
|
|
252
|
+
*
|
|
253
|
+
* The state domain's source is the running workload, not a file, so `load` reads the cluster
|
|
254
|
+
* rather than the disk. What it writes is the collected reading, which is what `publish`
|
|
255
|
+
* then exports.
|
|
256
|
+
* @param {object} context - Normalized domain context.
|
|
257
|
+
* @returns {{workload: string, status: string|null, pods: number}} What was collected.
|
|
258
|
+
* @memberof UnderpostState
|
|
259
|
+
*/
|
|
260
|
+
load(context = {}) {
|
|
261
|
+
context = domainContextFactory(context);
|
|
262
|
+
const observation = UnderpostState.API.observe(context);
|
|
263
|
+
const status = normalizeContainerStatus(observation.status) ?? null;
|
|
264
|
+
if (context.dryRun) {
|
|
265
|
+
logger.info('[dry-run] state load would record the observation', {
|
|
266
|
+
workload: observation.workload,
|
|
267
|
+
status,
|
|
268
|
+
});
|
|
269
|
+
return { workload: observation.workload, status, pods: observation.pods?.length ?? 0 };
|
|
270
|
+
}
|
|
271
|
+
if (status) store.set(CONTAINER_STATUS_KEY, containerStatusValue(observation.workload, context.env, status));
|
|
272
|
+
logger.info('Runtime state collected', {
|
|
273
|
+
workload: observation.workload,
|
|
274
|
+
status,
|
|
275
|
+
pods: observation.pods?.length ?? 0,
|
|
276
|
+
});
|
|
277
|
+
return { workload: observation.workload, status, pods: observation.pods?.length ?? 0 };
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Exports the observation off-cluster.
|
|
282
|
+
*
|
|
283
|
+
* The inverse of `load` for the other domains is a write back to the durable source; this
|
|
284
|
+
* domain has none, so the outward direction is the export instead. Under GitHub Actions the
|
|
285
|
+
* observation becomes workflow commands on stdout — the one transport that survives the SSH
|
|
286
|
+
* hop a remote deploy runs over — and, on a runner, `$GITHUB_OUTPUT` and
|
|
287
|
+
* `$GITHUB_STEP_SUMMARY` as well. Anywhere else it is JSON on stdout.
|
|
288
|
+
* @param {object} context - Normalized domain context.
|
|
289
|
+
* @returns {object} The exported observation.
|
|
290
|
+
* @memberof UnderpostState
|
|
291
|
+
*/
|
|
292
|
+
publish(context = {}) {
|
|
293
|
+
context = domainContextFactory(context);
|
|
294
|
+
const observation = UnderpostState.API.observe(context);
|
|
295
|
+
if (context.dryRun) {
|
|
296
|
+
logger.info('[dry-run] state publish would export the observation', {
|
|
297
|
+
workload: observation.workload,
|
|
298
|
+
target: inGithubActions() ? 'github-actions' : 'stdout',
|
|
299
|
+
});
|
|
300
|
+
return observation;
|
|
301
|
+
}
|
|
302
|
+
if (inGithubActions()) exportToGithubActions(observation);
|
|
303
|
+
else console.log(JSON.stringify(observation, null, 2));
|
|
304
|
+
return observation;
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Stamps a contract phase into the live runtime.
|
|
309
|
+
*
|
|
310
|
+
* `--args phase=<phase>` selects it, defaulting to the phase already observed, so a bare
|
|
311
|
+
* `state apply` re-asserts what is true rather than inventing a transition. This is the same
|
|
312
|
+
* write the in-pod lifecycle hooks perform, which is why they call the state domain and not
|
|
313
|
+
* the host one.
|
|
314
|
+
* @param {object} context - Normalized domain context.
|
|
315
|
+
* @returns {{workload: string, phase: string}} What was stamped.
|
|
316
|
+
* @memberof UnderpostState
|
|
317
|
+
*/
|
|
318
|
+
apply(context = {}) {
|
|
319
|
+
context = domainContextFactory(context);
|
|
320
|
+
const workload = workloadId(context) || `${process.env.DEPLOY_ID || ''}`.trim();
|
|
321
|
+
const requested = `${context.args['phase'] ?? ''}`.trim();
|
|
322
|
+
const phase = requested || UnderpostState.API.observe(context).status || RUNTIME_STATUS.INIT;
|
|
323
|
+
const known = Object.values(RUNTIME_STATUS);
|
|
324
|
+
if (requested && !known.includes(requested))
|
|
325
|
+
throw new Error(`[state] unknown phase: ${requested} (expected ${known.join(', ')})`);
|
|
326
|
+
if (context.dryRun) {
|
|
327
|
+
logger.info('[dry-run] state apply would stamp the runtime phase', { workload, phase });
|
|
328
|
+
return { workload, phase };
|
|
329
|
+
}
|
|
330
|
+
setRuntimeStatus(workload, context.env, phase);
|
|
331
|
+
return { workload, phase };
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Read-only report: the observation, plus where this agent is reading it from.
|
|
336
|
+
* @param {object} context - Normalized domain context.
|
|
337
|
+
* @returns {object} Report.
|
|
338
|
+
* @memberof UnderpostState
|
|
339
|
+
*/
|
|
340
|
+
status(context = {}) {
|
|
341
|
+
context = domainContextFactory(context);
|
|
342
|
+
const observation = UnderpostState.API.observe(context);
|
|
343
|
+
const report = {
|
|
344
|
+
domain: 'state',
|
|
345
|
+
env: context.env,
|
|
346
|
+
namespace: context.namespace,
|
|
347
|
+
store: store.path(),
|
|
348
|
+
source: UnderpostState.API.isInsideContainer() ? 'in-container' : 'cluster-exec',
|
|
349
|
+
...observation,
|
|
350
|
+
};
|
|
351
|
+
console.log(UnderpostState.API.table(observation, `${context.args.refresh ?? ''}`.trim()));
|
|
352
|
+
return report;
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Replaces the current projection: drops the latched status and re-stamps it from a fresh
|
|
357
|
+
* observation. The way out of a fatal latch that outlived the fault that set it.
|
|
358
|
+
* @param {object} context - Normalized domain context.
|
|
359
|
+
* @returns {{workload: string, phase: string}} The re-stamped phase.
|
|
360
|
+
* @memberof UnderpostState
|
|
361
|
+
*/
|
|
362
|
+
rotate(context = {}) {
|
|
363
|
+
context = domainContextFactory(context);
|
|
364
|
+
if (context.dryRun) {
|
|
365
|
+
logger.info('[dry-run] state rotate would clear and re-stamp the runtime phase');
|
|
366
|
+
return { workload: workloadId(context), phase: null };
|
|
367
|
+
}
|
|
368
|
+
store.delete(CONTAINER_STATUS_KEY);
|
|
369
|
+
return UnderpostState.API.apply(context);
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Withdraws the agent's local traces: removes the container state store.
|
|
374
|
+
* @param {object} context - Normalized domain context.
|
|
375
|
+
* @returns {{removed: string|null}} What was withdrawn.
|
|
376
|
+
* @memberof UnderpostState
|
|
377
|
+
*/
|
|
378
|
+
clean(context = {}) {
|
|
379
|
+
context = domainContextFactory(context);
|
|
380
|
+
const storePath = store.path();
|
|
381
|
+
if (context.dryRun) {
|
|
382
|
+
logger.info('[dry-run] state clean would remove the container state store', { store: storePath });
|
|
383
|
+
return { removed: storePath };
|
|
384
|
+
}
|
|
385
|
+
const existed = fs.existsSync(storePath);
|
|
386
|
+
if (existed) fs.removeSync(storePath);
|
|
387
|
+
logger.info('Container state store withdrawn', { store: existed ? storePath : null });
|
|
388
|
+
return { removed: existed ? storePath : null };
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export default UnderpostState;
|
|
394
|
+
export { UnderpostState, workloadId };
|
package/src/cli/static.js
CHANGED
|
@@ -7,10 +7,10 @@ import fs from 'fs-extra';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import express from 'express';
|
|
9
9
|
import { ssrFactory } from '../client-builder/ssr.js';
|
|
10
|
-
import { shellExec } from '../server/process.js';
|
|
10
|
+
import { shellExec } from '../server/runtime/process.js';
|
|
11
11
|
import Underpost from '../index.js';
|
|
12
12
|
import { JSONweb } from '../client-builder/client-formatted.js';
|
|
13
|
-
import { loggerFactory, loggerMiddleware } from '../server/logger.js';
|
|
13
|
+
import { loggerFactory, loggerMiddleware } from '../server/ops/logger.js';
|
|
14
14
|
const logger = loggerFactory(import.meta);
|
|
15
15
|
/**
|
|
16
16
|
* @typedef {Object} MetadataOptions
|
package/src/cli/system.js
CHANGED