@underpostnet/cyberia 3.3.0 → 3.3.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.env.example +17 -5
- package/.github/workflows/coverall.cyberia.ci.yml +39 -14
- package/.github/workflows/cyberia-client.cd.yml +5 -0
- package/.github/workflows/cyberia-server.cd.yml +5 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
- package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
- package/.github/workflows/engine-cyberia.cd.yml +3 -0
- package/.github/workflows/engine-cyberia.ci.yml +4 -5
- package/.github/workflows/ghpkg.ci.yml +35 -20
- package/.github/workflows/hardhat.ci.yml +12 -11
- package/.github/workflows/npmpkg.ci.yml +17 -15
- package/.github/workflows/publish.cyberia.ci.yml +44 -0
- package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
- package/.github/workflows/release.cd.yml +1 -0
- package/.prettierignore +1 -0
- package/AGENTS.md +96 -0
- package/CHANGELOG.md +653 -2513
- package/CLI-HELP.md +323 -157
- package/Dockerfile +25 -9
- package/Dockerfile.dev +25 -9
- package/Dockerfile.test +5 -5
- package/README.md +48 -28
- package/bin/build.js +86 -41
- package/bin/build.template.js +8 -3
- package/bin/cyberia.js +1494 -1403
- package/bin/deploy.js +18 -104
- package/bin/index.js +1494 -1403
- package/compose.env +17 -5
- package/conf.js +98 -7
- package/deploy/cyberia-client/deploy.sh +46 -0
- package/deploy/cyberia-client/package.sh +17 -0
- package/deploy/cyberia-client/state.sh +15 -0
- package/deploy/cyberia-server/deploy.sh +46 -0
- package/deploy/cyberia-server/package.sh +17 -0
- package/deploy/cyberia-server/state.sh +15 -0
- package/deploy/dd-cyberia/deploy.sh +9 -29
- package/deploy/dd-cyberia/init.sh +38 -45
- package/deploy/dd-cyberia/package.sh +16 -0
- package/deploy/dd-cyberia/state.sh +14 -0
- package/deploy/dd-cyberia/sync-deploy.sh +133 -147
- package/deploy/lib/config.sh +29 -0
- package/deploy/lib/github-actions-logging.sh +610 -0
- package/deploy/lib/host.sh +194 -0
- package/deploy/lib/state.sh +65 -0
- package/deploy/pwa-microservices-template/deploy.sh +17 -42
- package/deploy/release/deploy.sh +9 -41
- package/deployment.yaml +7 -2
- package/docker-compose.yml +23 -17
- package/examples/static-page/README.md +19 -19
- package/examples/static-page/ssr-components/CustomPage.js +2 -2
- package/hardhat/hardhat.config.js +1 -6
- package/hardhat/package-lock.json +101 -40
- package/hardhat/package.json +2 -2
- package/manifests/alertmanager/deployment.yaml +81 -0
- package/manifests/blackbox-exporter/deployment.yaml +75 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +32 -7
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +32 -7
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +46 -27
- package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
- package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
- package/manifests/deployment/mongo-express/service.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
- package/manifests/grafana/deployment.yaml +26 -7
- package/manifests/grafana/kustomization.yaml +1 -0
- package/manifests/grafana/service.yaml +6 -1
- package/manifests/mariadb/pv.yaml +1 -0
- package/manifests/mongodb/statefulset.yaml +9 -2
- package/manifests/mysql/pv-pvc.yaml +14 -1
- package/manifests/postgresql/pv.yaml +12 -1
- package/manifests/postgresql/pvc.yaml +1 -0
- package/manifests/prometheus/deployment.yaml +18 -22
- package/package.json +87 -12
- package/scripts/event-monitor.sh +56 -0
- package/scripts/k3s-node-setup.sh +27 -14
- package/scripts/kubeadm-node-setup.sh +31 -11
- package/scripts/maas-setup.sh +8 -8
- package/scripts/selinux-normalize.sh +907 -0
- package/scripts/shutdown-machine.sh +843 -0
- package/scripts/test-monitor.sh +5 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +15 -10
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +7 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +90 -186
- package/src/api/core/core.controller.js +1 -1
- package/src/api/core/core.router.js +2 -2
- package/src/api/core/core.service.js +2 -2
- package/src/api/crypto/crypto.controller.js +1 -1
- package/src/api/crypto/crypto.service.js +1 -1
- package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +3 -3
- package/src/api/cyberia-action/cyberia-action.service.js +5 -6
- package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
- package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
- package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
- package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +2 -4
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +13 -35
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +17 -34
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
- package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.service.js +3 -3
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +468 -5
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +502 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +29 -40
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +35 -142
- package/src/api/cyberia-instance/cyberia-instance.controller.js +2 -5
- package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
- package/src/api/cyberia-instance/cyberia-instance.router.js +5 -18
- package/src/api/cyberia-instance/cyberia-instance.service.js +5 -45
- package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +76 -3
- package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
- package/src/api/cyberia-map/cyberia-map.router.js +1 -1
- package/src/api/cyberia-map/cyberia-map.service.js +8 -4
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +4 -4
- package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
- package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -214
- package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
- package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
- package/src/api/default/default.controller.js +1 -1
- package/src/api/default/default.router.js +1 -1
- package/src/api/default/default.service.js +2 -2
- package/src/api/document/document.controller.js +1 -1
- package/src/api/document/document.router.js +1 -1
- package/src/api/document/document.service.js +2 -2
- package/src/api/file/file.controller.js +1 -1
- package/src/api/file/file.ref.js +153 -0
- package/src/api/file/file.ref.json +11 -2
- package/src/api/file/file.router.js +1 -1
- package/src/api/file/file.service.js +2 -2
- package/src/api/instance/instance.controller.js +1 -1
- package/src/api/instance/instance.router.js +1 -1
- package/src/api/instance/instance.service.js +2 -2
- package/src/api/ipfs/ipfs.controller.js +1 -1
- package/src/api/ipfs/ipfs.router.js +2 -2
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +1 -1
- package/src/api/object-layer/object-layer.model.js +47 -12
- package/src/api/object-layer/object-layer.router.js +12 -5
- package/src/api/object-layer/object-layer.service.js +116 -123
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
- package/src/api/test/test.controller.js +1 -1
- package/src/api/test/test.service.js +1 -1
- package/src/api/user/guest.service.js +3 -3
- package/src/api/user/user.controller.js +1 -1
- package/src/api/user/user.router.js +2 -2
- package/src/api/user/user.service.js +4 -4
- package/src/api.js +5 -9
- package/src/cli/app.js +402 -0
- package/src/cli/baremetal.js +30 -35
- package/src/cli/client.js +306 -0
- package/src/cli/cloud-init.js +3 -3
- package/src/cli/cluster.js +191 -82
- package/src/cli/db.js +120 -68
- package/src/cli/deploy.js +157 -75
- package/src/cli/docker-compose.js +5 -5
- package/src/cli/domains.js +184 -0
- package/src/cli/dotenv-store.js +143 -0
- package/src/cli/event.js +2281 -0
- package/src/cli/fs-selection.js +115 -0
- package/src/cli/fs.js +159 -343
- package/src/cli/host.js +672 -0
- package/src/cli/image.js +4 -6
- package/src/cli/index.js +343 -151
- package/src/cli/ipfs.js +34 -30
- package/src/cli/kickstart.js +1 -1
- package/src/cli/kubectl.js +218 -41
- package/src/cli/lxd.js +3 -3
- package/src/cli/monitor.js +1359 -26
- package/src/cli/package.js +90 -0
- package/src/cli/release.js +16 -12
- package/src/cli/repository.js +586 -363
- package/src/cli/run.js +398 -843
- package/src/cli/secrets.js +2158 -964
- package/src/cli/ssh.js +478 -279
- package/src/cli/state.js +394 -0
- package/src/cli/static.js +2 -2
- package/src/cli/system.js +1 -1
- package/src/cli/test.js +203 -125
- package/src/cli/vultr.js +61 -21
- package/src/cli/wireguard.js +1112 -306
- package/src/client/components/core/CalendarCore.js +53 -96
- package/src/client/components/core/Docs.js +327 -303
- package/src/client/components/core/FileExplorer.js +0 -21
- package/src/client/components/core/Modal.js +56 -1
- package/src/client/components/core/PanelForm.js +4 -4
- package/src/client/components/core/Repository.js +56 -0
- package/src/client/components/core/Translate.js +7 -0
- package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
- package/src/client/components/core/Wallet.js +0 -11
- package/src/client/components/core/Worker.js +7 -1
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
- package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
- package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
- package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
- package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
- package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +2 -35
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -1
- package/src/client/components/default/SettingsDefault.js +2 -2
- package/src/client/components/itemledger/SettingsItemledger.js +2 -2
- package/src/client/components/underpost/AppShellUnderpost.js +3 -2
- package/src/client/components/underpost/SettingsUnderpost.js +2 -2
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +313 -30
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
- package/src/client/public/cyberia-docs/CYBERIA.md +48 -28
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-384x384.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-512x512.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/default/assets/background/white.jpg +0 -0
- package/src/client/public/default/browserconfig.xml +1 -1
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon-48x48.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/manifest.webmanifest +5 -5
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/yandex-browser-50x50.png +0 -0
- package/src/client/public/default/yandex-browser-manifest.json +1 -1
- package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
- package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
- package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -10
- package/src/client/services/object-layer/object-layer.service.js +3 -1
- package/src/client/ssr/RootDocument.js +1 -1
- package/src/client/ssr/body/404.js +1 -1
- package/src/client/ssr/body/500.js +1 -1
- package/src/client/ssr/body/CacheControl.js +1 -1
- package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
- package/src/client/ssr/head/CryptokoynScripts.js +1 -1
- package/src/client/ssr/head/Css.js +1 -1
- package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +1 -1
- package/src/client/ssr/head/ItemledgerScripts.js +1 -1
- package/src/client/ssr/head/Microdata.js +1 -1
- package/src/client/ssr/head/Production.js +1 -1
- package/src/client/ssr/head/Pwa.js +1 -1
- package/src/client/ssr/head/PwaItemledger.js +1 -1
- package/src/client/ssr/head/Seo.js +1 -1
- package/src/client/ssr/head/UnderpostScripts.js +1 -1
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
- package/src/client/ssr/views/Cyberia404.js +7 -5
- package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/views/Maintenance.js +1 -1
- package/src/client/ssr/views/NoNetworkConnection.js +1 -1
- package/src/client/ssr/views/Test.js +1 -1
- package/src/client/sw/core.sw.js +20 -14
- package/src/client-builder/client-build-docs.js +92 -77
- package/src/client-builder/client-build-live.js +2 -2
- package/src/client-builder/client-build.js +105 -74
- package/src/client-builder/client-bundle.js +347 -0
- package/src/client-builder/client-dev-server.js +3 -3
- package/src/client-builder/client-icons.js +2 -2
- package/src/client-builder/ssr.js +3 -3
- package/src/client.build.js +3 -6
- package/src/client.dev.js +3 -6
- package/src/db/DataBaseProvider.js +186 -3
- package/src/db/mariadb/MariaDB.js +3 -2
- package/src/db/mongo/MongoBootstrap.js +273 -101
- package/src/db/mongo/MongoExpress.js +187 -0
- package/src/db/mongo/MongooseDB.js +7 -8
- package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
- package/src/grpc/cyberia/grpc-server.js +6 -8
- package/src/index.js +79 -23
- package/src/mailer/EmailRender.js +2 -2
- package/src/mailer/MailerInterceptor.js +87 -0
- package/src/mailer/MailerProvider.js +50 -6
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +144 -147
- package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
- package/src/projects/cyberia/besu-genesis-generator.js +8 -17
- package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
- package/src/projects/cyberia/catalog-cyberia.js +54 -10
- package/src/projects/cyberia/gemini-client.js +4 -4
- package/src/projects/cyberia/generate-saga.js +5 -12
- package/src/projects/cyberia/hot-reload-trigger.js +18 -29
- package/src/projects/cyberia/instance-backup.js +210 -0
- package/src/projects/cyberia/instance-data.js +178 -258
- package/src/projects/cyberia/ipfs-client.js +4 -4
- package/src/projects/cyberia/map-preview-generator.js +33 -69
- package/src/projects/cyberia/object-layer.js +153 -320
- package/src/projects/cyberia/seed-audio.js +139 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
- package/src/projects/cyberia/semantic-layer-generator.js +3 -19
- package/src/projects/cyberia/stat-balance.js +81 -0
- package/src/projects/cyberia/stat-commands.js +23 -0
- package/src/projects/cyberia/stat-contract-generator.js +101 -0
- package/src/projects/underpost/catalog-underpost.js +9 -1
- package/src/proxy.js +4 -7
- package/src/runtime/cyberia-client/Dockerfile +17 -8
- package/src/runtime/cyberia-client/Dockerfile.dev +13 -4
- package/src/runtime/cyberia-server/Dockerfile +18 -6
- package/src/runtime/cyberia-server/Dockerfile.dev +16 -3
- package/src/runtime/engine-cyberia/Dockerfile +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.test +5 -5
- package/src/runtime/engine-cyberia/compose.env +17 -5
- package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
- package/src/runtime/express/Express.js +32 -27
- package/src/runtime/lampp/Lampp.js +22 -70
- package/src/runtime/nginx/Nginx.js +1 -1
- package/src/runtime/wp/Wp.js +16 -48
- package/src/server/{catalog.js → build/catalog.js} +15 -5
- package/src/server/build/coverage.js +188 -0
- package/src/server/build/execution.js +402 -0
- package/src/server/build/package.js +508 -0
- package/src/server/build/testing.js +578 -0
- package/src/server/{dns.js → network/dns.js} +144 -11
- package/src/server/{forward-proxy.js → network/forward-proxy.js} +10 -18
- package/src/server/{middlewares.js → network/middlewares.js} +11 -5
- package/src/server/network/node-capability.js +98 -0
- package/src/server/{peer.js → network/peer.js} +3 -3
- package/src/server/{proxy.js → network/proxy.js} +7 -13
- package/src/server/network/router.js +356 -0
- package/src/server/{tls.js → network/tls.js} +2 -2
- package/src/server/{underpost-compression.js → network/underpost-compression.js} +1 -1
- package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +7 -7
- package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +2 -2
- package/src/server/{cri.js → ops/cri.js} +2 -2
- package/src/server/{cron.js → ops/cron.js} +349 -74
- package/src/server/ops/event-notification.js +284 -0
- package/src/server/{logger.js → ops/logger.js} +143 -23
- package/src/server/ops/monitoring.js +1724 -0
- package/src/server/{systemd.js → ops/systemd.js} +55 -1
- package/src/server/{conf.js → runtime/conf.js} +516 -423
- package/src/server/runtime/config-scope.js +215 -0
- package/src/server/runtime/environment.js +149 -0
- package/src/server/{process.js → runtime/process.js} +153 -12
- package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
- package/src/server/{runtime.js → runtime/runtime.js} +12 -8
- package/src/server/{start.js → runtime/start.js} +128 -39
- package/src/server/{auth.js → security/auth.js} +7 -8
- package/src/server/security/container-storage.js +382 -0
- package/src/server/{crypto.js → security/crypto.js} +1 -1
- package/src/server/{selinux.js → security/selinux.js} +1 -1
- package/src/server/{backup.js → storage/backup.js} +17 -8
- package/src/server/{data-query.js → storage/data-query.js} +17 -1
- package/src/server/storage/downloader.js +121 -0
- package/src/server/storage/repository.js +68 -0
- package/src/server/storage/zip.js +153 -0
- package/src/server.js +4 -7
- package/src/ws/IoInterface.js +1 -1
- package/src/ws/IoServer.js +1 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/src/ws/default/default.ws.connection.js +1 -1
- package/src/ws/default/default.ws.emit.js +1 -1
- package/src/ws/default/default.ws.server.js +1 -1
- package/test/e2e/event-e2e-public-ingress-down.js +45 -0
- package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
- package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
- package/test/{api.test.js → integration/app/api.test.js} +33 -14
- package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +64 -0
- package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
- package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +17 -23
- package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
- package/test/integration/app/cyberia/cyberia-load.test.js +466 -0
- package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
- package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +338 -0
- package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
- package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
- package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
- package/test/integration/app/cyberia/seed-audio.test.js +275 -0
- package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
- package/test/integration/infra/1-security/config-scope.test.js +305 -0
- package/test/integration/infra/1-security/container-storage.test.js +356 -0
- package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
- package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
- package/test/{selinux.test.js → integration/infra/1-security/selinux.test.js} +2 -4
- package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
- package/test/integration/infra/1-security/systemd-service.test.js +70 -0
- package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
- package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
- package/test/integration/infra/2-network/node-capability.test.js +182 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +1187 -0
- package/test/{wireguard-edge.test.js → integration/infra/2-network/wireguard-edge.test.js} +649 -55
- package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
- package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
- package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
- package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
- package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
- package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
- package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
- package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
- package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +6 -6
- package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +4 -4
- package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
- package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
- package/test/integration/infra/5-observability/event-notification.test.js +197 -0
- package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
- package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
- package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
- package/test/support/shell-harness.js +73 -0
- package/test/unit/build-template.test.js +97 -0
- package/test/unit/build-workflow-offline.test.js +132 -0
- package/test/unit/catalog.test.js +71 -0
- package/test/unit/client-build-docs.test.js +361 -0
- package/test/unit/client-bundle.test.js +313 -0
- package/test/unit/conf-loading.test.js +303 -0
- package/test/unit/conf-resolution.test.js +996 -0
- package/test/unit/coverage-artifact.test.js +221 -0
- package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
- package/test/unit/cyberia/instance-backup.test.js +183 -0
- package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
- package/test/unit/cyberia/publish-workflow.test.js +22 -0
- package/test/unit/cyberia/stat-balance.test.js +69 -0
- package/test/unit/deploy-env-resolution.test.js +38 -0
- package/test/unit/deploy-log-table.test.js +518 -0
- package/test/unit/downloader-integrity.test.js +98 -0
- package/test/unit/execution-profiles.test.js +219 -0
- package/test/unit/file-reference-registry.test.js +141 -0
- package/test/unit/fleet-sync-source.test.js +149 -0
- package/test/unit/fs-storage-paths.test.js +596 -0
- package/test/unit/logger-redaction.test.js +141 -0
- package/test/unit/package.test.js +457 -0
- package/test/unit/prepare-host.test.js +382 -0
- package/test/unit/process-environment.test.js +18 -0
- package/test/unit/propagation-message.test.js +78 -0
- package/test/unit/redeploy-plan.test.js +24 -0
- package/test/unit/release-bump.test.js +474 -0
- package/test/unit/ssh-output-redaction.test.js +28 -0
- package/test/unit/start-options.test.js +46 -0
- package/test/unit/test-tiers.test.js +220 -0
- package/test/unit/zip-archive.test.js +142 -0
- package/vitest.config.js +66 -0
- package/.nycrc +0 -9
- package/deploy/lib/logging.sh +0 -96
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
- package/manifests/mongodb/pv-pvc.yaml +0 -59
- package/scripts/coverall-test-cyberia.sh +0 -24
- package/scripts/coverall-test.sh +0 -24
- package/scripts/link-local-underpost-cli.sh +0 -6
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
- package/src/api/user/user.build.js +0 -16
- package/src/cli/env.js +0 -177
- package/src/client/components/core/Blockchain.js +0 -41
- package/src/client/components/core/Blog.js +0 -9
- package/src/client/components/core/KeyboardAvoidance.js +0 -145
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/white0-min.jpg +0 -0
- package/src/client/public/default/assets/background/white0.jpg +0 -0
- package/src/client/public/doc/favicon.ico +0 -0
- package/src/client/public/doc/sitemap +0 -148
- package/src/server/downloader.js +0 -73
- package/src/server/environment.js +0 -98
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
# Logging helpers for deploy/<deploy-id>/*.sh. Sourced, never executed directly.
|
|
2
|
+
#
|
|
3
|
+
# Environment read by these helpers, and nothing else:
|
|
4
|
+
# RUN_QUIET_DEBUG Stream every line verbatim: no table, no folding, no dropped traces. For an
|
|
5
|
+
# operator watching a step over SSH who needs the run itself, not a report of
|
|
6
|
+
# it. Wins over the two below, which each hide part of the stream by design.
|
|
7
|
+
# RUN_QUIET_CI Marks stdout as a GitHub Actions log, which folds monitor frames into
|
|
8
|
+
# collapsed sections. The CD workflows export it on the far side of the SSH
|
|
9
|
+
# hop because GITHUB_ACTIONS is runner-local and does not travel; a remote
|
|
10
|
+
# deploy has no other way to know. `underpost state publish` reads the same
|
|
11
|
+
# pair to choose workflow commands over JSON.
|
|
12
|
+
# RUN_QUIET_PLAIN No colour, no cursor motion, no folding: frames stream as they arrive.
|
|
13
|
+
# NO_COLOR Colour off, the usual convention. Everything else is unaffected.
|
|
14
|
+
#
|
|
15
|
+
# Whatever the rendering, the parsing behind it is the same: a step that reports a fatal runtime
|
|
16
|
+
# status fails, including one that exits 0, and including in debug mode.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if [ -n "${NO_COLOR:-}${RUN_QUIET_PLAIN:-}" ]; then
|
|
20
|
+
RUN_QUIET_RED=''
|
|
21
|
+
RUN_QUIET_RESET=''
|
|
22
|
+
else
|
|
23
|
+
RUN_QUIET_RED=$'\033[0;31m'
|
|
24
|
+
RUN_QUIET_RESET=$'\033[0m'
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
RUN_QUIET_NODE_TAG=$(hostname 2>/dev/null | tr '[:upper:]' '[:lower:]')
|
|
28
|
+
RUN_QUIET_NODE_TAG=${RUN_QUIET_NODE_TAG:+ [$RUN_QUIET_NODE_TAG]}
|
|
29
|
+
|
|
30
|
+
# The report pattern and the passthrough window describe the deployment log
|
|
31
|
+
# format, not any one step, so they are declared once here instead of being
|
|
32
|
+
# repeated at every call site.
|
|
33
|
+
DEPLOY_REPORT_PATTERN='Target pod:'
|
|
34
|
+
DEPLOY_REPORT_LINES_AFTER=14
|
|
35
|
+
|
|
36
|
+
# Titles a deploy run, in the same shape as the step lines below it.
|
|
37
|
+
deploy_start() {
|
|
38
|
+
echo "$RUN_QUIET_NODE_TAG $(date -Is) ▶▶ $1"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# One deploy step: a label and the command that carries it.
|
|
42
|
+
deploy_step() {
|
|
43
|
+
local label="$1"
|
|
44
|
+
shift
|
|
45
|
+
|
|
46
|
+
run_quiet "$label" "$DEPLOY_REPORT_PATTERN" "$DEPLOY_REPORT_LINES_AFTER" "$@"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
run_quiet() {
|
|
50
|
+
local label="$1"
|
|
51
|
+
local patterns="$2"
|
|
52
|
+
local lines_after="$3"
|
|
53
|
+
shift 3
|
|
54
|
+
|
|
55
|
+
local debug_log
|
|
56
|
+
local error_log
|
|
57
|
+
local fail_flag
|
|
58
|
+
local fatal
|
|
59
|
+
local fifo_dir
|
|
60
|
+
local filter_pid
|
|
61
|
+
local stderr_pid
|
|
62
|
+
local color=0
|
|
63
|
+
local debug=0
|
|
64
|
+
local groups=0
|
|
65
|
+
local redraw=0
|
|
66
|
+
local width=0
|
|
67
|
+
local rows=0
|
|
68
|
+
local status=0
|
|
69
|
+
|
|
70
|
+
echo "$RUN_QUIET_NODE_TAG $(date -Is) ▶ $label"
|
|
71
|
+
|
|
72
|
+
# How a step renders is decided by what its destination can do, not by preference, and the
|
|
73
|
+
# three renderings are mutually exclusive:
|
|
74
|
+
# debug an operator watching over SSH — nothing filtered, folded or overwritten
|
|
75
|
+
# redraw a terminal — one live region, rewritten in place
|
|
76
|
+
# groups a GitHub Actions log — no cursor motion, so frames fold into a collapsed section
|
|
77
|
+
# With none of them the frames simply stream. RUN_QUIET_DEBUG is resolved first because it
|
|
78
|
+
# is the operator asking to see the stream itself, which neither of the others can show: a
|
|
79
|
+
# live region overwrites what came before, and a collapsed section hides it.
|
|
80
|
+
[ -z "${RUN_QUIET_DEBUG:-}" ] || debug=1
|
|
81
|
+
|
|
82
|
+
[ -n "${NO_COLOR:-}${RUN_QUIET_PLAIN:-}" ] || color=1
|
|
83
|
+
|
|
84
|
+
if [ "$debug" -eq 0 ] && [ -t 1 ] && [ "${TERM:-dumb}" != dumb ] && [ -z "${RUN_QUIET_PLAIN:-}" ]; then
|
|
85
|
+
redraw=1
|
|
86
|
+
width=${COLUMNS:-0}
|
|
87
|
+
[ "$width" -gt 0 ] 2>/dev/null || width=$(tput cols 2>/dev/null || echo 0)
|
|
88
|
+
rows=${LINES:-0}
|
|
89
|
+
[ "$rows" -gt 0 ] 2>/dev/null || rows=$(tput lines 2>/dev/null || echo 0)
|
|
90
|
+
# Without a known width a long row wraps, and the cursor-up count that
|
|
91
|
+
# addresses the table no longer matches the lines it printed.
|
|
92
|
+
[ "$width" -ge 20 ] || redraw=0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# GITHUB_ACTIONS exists on a runner but is not carried across the SSH hop a remote deploy runs
|
|
96
|
+
# over, so RUN_QUIET_CI — which the workflows export on the far side — is what actually marks
|
|
97
|
+
# a step whose stdout a GitHub log will render.
|
|
98
|
+
if [ "$debug" -eq 0 ] && [ "$redraw" -eq 0 ] && [ -z "${RUN_QUIET_PLAIN:-}" ] &&
|
|
99
|
+
[ -n "${GITHUB_ACTIONS:-}${RUN_QUIET_CI:-}" ]; then
|
|
100
|
+
groups=1
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
debug_log=$(mktemp --suffix=.debug.log)
|
|
104
|
+
error_log=$(mktemp --suffix=.error.log)
|
|
105
|
+
fail_flag=$(mktemp --suffix=.fatal)
|
|
106
|
+
: >"$fail_flag"
|
|
107
|
+
fifo_dir=$(mktemp -d)
|
|
108
|
+
mkfifo "$fifo_dir/merged" "$fifo_dir/stderr"
|
|
109
|
+
|
|
110
|
+
# The filter reads the live stream rather than the finished log: a deployment
|
|
111
|
+
# monitor prints its report for minutes before exiting, so a pass over the
|
|
112
|
+
# completed file would show nothing until then. fflush defeats awk's block
|
|
113
|
+
# buffering, which otherwise withholds output whenever stdout is a pipe.
|
|
114
|
+
# awk writes the debug log itself rather than piping through tee, so the
|
|
115
|
+
# reader stays a single process that a kill can always release.
|
|
116
|
+
#
|
|
117
|
+
# On a terminal the table is the only live region and always sits at the
|
|
118
|
+
# bottom: rows are overwritten one by one (cursor up, then erase to end of
|
|
119
|
+
# line as each row is rewritten) so the section never blanks between frames,
|
|
120
|
+
# and a passthrough line is printed after erasing the table and before
|
|
121
|
+
# drawing it again. All of that is cursor relative, so every row must occupy
|
|
122
|
+
# exactly one terminal line: rows are cut to the terminal width, counting
|
|
123
|
+
# display columns rather than bytes so colour escapes neither inflate the
|
|
124
|
+
# measurement nor get sliced in half. Elsewhere nothing is cut and nothing
|
|
125
|
+
# is overwritten — the frames stream, folded into a CI group when there is
|
|
126
|
+
# one to fold them into.
|
|
127
|
+
awk \
|
|
128
|
+
-v pattern="$patterns" \
|
|
129
|
+
-v lines_after="$lines_after" \
|
|
130
|
+
-v debug_log="$debug_log" \
|
|
131
|
+
-v redraw="$redraw" \
|
|
132
|
+
-v color="$color" \
|
|
133
|
+
-v debug="$debug" \
|
|
134
|
+
-v groups="$groups" \
|
|
135
|
+
-v label="$label" \
|
|
136
|
+
-v width="$width" \
|
|
137
|
+
-v rows="$rows" \
|
|
138
|
+
-v started="$(date +%H:%M:%S)" \
|
|
139
|
+
-v fail_flag="$fail_flag" \
|
|
140
|
+
-v handoff="$RUN_QUIET_NODE_TAG $(date -Is) ▶ Switch traffic" '
|
|
141
|
+
function strip(s) {
|
|
142
|
+
gsub(esc_seq, "", s)
|
|
143
|
+
return s
|
|
144
|
+
}
|
|
145
|
+
function pad(s, w) {
|
|
146
|
+
while (length(s) < w) s = s " "
|
|
147
|
+
return s
|
|
148
|
+
}
|
|
149
|
+
# Pod names differ in their tail, so a name too wide for its column keeps
|
|
150
|
+
# the end rather than the deploy prefix every pod shares.
|
|
151
|
+
function trim(s, w) {
|
|
152
|
+
return length(s) <= w ? s : ".." substr(s, length(s) - w + 3)
|
|
153
|
+
}
|
|
154
|
+
function rule(n, r) {
|
|
155
|
+
r = ""
|
|
156
|
+
while (n-- > 0) r = r "-"
|
|
157
|
+
return r
|
|
158
|
+
}
|
|
159
|
+
function paint(s, sgr) {
|
|
160
|
+
return color ? esc "[" sgr "m" s esc "[0m" : s
|
|
161
|
+
}
|
|
162
|
+
function fit(s, out, visible) {
|
|
163
|
+
if (!redraw) return s
|
|
164
|
+
out = ""
|
|
165
|
+
visible = 0
|
|
166
|
+
while (length(s) > 0) {
|
|
167
|
+
if (match(s, "^" esc_seq)) {
|
|
168
|
+
out = out substr(s, 1, RLENGTH)
|
|
169
|
+
s = substr(s, RLENGTH + 1)
|
|
170
|
+
continue
|
|
171
|
+
}
|
|
172
|
+
if (visible >= width - 1) return out esc "[0m"
|
|
173
|
+
out = out substr(s, 1, 1)
|
|
174
|
+
s = substr(s, 2)
|
|
175
|
+
visible++
|
|
176
|
+
}
|
|
177
|
+
return out
|
|
178
|
+
}
|
|
179
|
+
function put(line) {
|
|
180
|
+
printf "%s%s\n", fit(line), redraw ? esc "[K" : ""
|
|
181
|
+
fflush()
|
|
182
|
+
}
|
|
183
|
+
# GitHub renders no cursor motion, so the live region becomes a
|
|
184
|
+
# collapsed section: every frame streams into it and the settled table
|
|
185
|
+
# is reprinted outside it.
|
|
186
|
+
function open_group() {
|
|
187
|
+
if (!groups || group_open) return
|
|
188
|
+
group_open = 1
|
|
189
|
+
printf "::group::%s monitor frames\n", label
|
|
190
|
+
fflush()
|
|
191
|
+
}
|
|
192
|
+
function close_group() {
|
|
193
|
+
if (!group_open) return
|
|
194
|
+
group_open = 0
|
|
195
|
+
# The next run of rows opens its own section, and a section starts
|
|
196
|
+
# with its title and header.
|
|
197
|
+
appended_header = 0
|
|
198
|
+
appended_cycle = 0
|
|
199
|
+
printf "::endgroup::\n"
|
|
200
|
+
fflush()
|
|
201
|
+
}
|
|
202
|
+
function final_table( i) {
|
|
203
|
+
if (!groups || pod_count == 0) return
|
|
204
|
+
close_group()
|
|
205
|
+
measure()
|
|
206
|
+
title_line()
|
|
207
|
+
header_lines()
|
|
208
|
+
for (i = 1; i <= pod_count; i++) pod_line(pods[i])
|
|
209
|
+
}
|
|
210
|
+
function json_value(key, found) {
|
|
211
|
+
if (!match($0, "\"" key "\"[ ]*:[ ]*\"[^\"]*\"")) return ""
|
|
212
|
+
found = substr($0, RSTART, RLENGTH)
|
|
213
|
+
sub("^\"" key "\"[ ]*:[ ]*\"", "", found)
|
|
214
|
+
sub("\"$", "", found)
|
|
215
|
+
return found
|
|
216
|
+
}
|
|
217
|
+
function apply_event( was_k8s_ready, was_runtime_ready, i) {
|
|
218
|
+
events_seen = 1
|
|
219
|
+
was_k8s_ready = k8s_ready
|
|
220
|
+
was_runtime_ready = runtime_ready
|
|
221
|
+
if (event_phase == "kubernetes") k8s_ready = (event_state == "pod_ready")
|
|
222
|
+
else if (event_phase == "runtime") {
|
|
223
|
+
runtime_ready = (event_state == "runtime_ready")
|
|
224
|
+
if (event_status != "") last_runtime = event_status
|
|
225
|
+
if (is_fatal(event_status)) note_fatal("runtime event", "status=" event_status)
|
|
226
|
+
}
|
|
227
|
+
if (redraw) {
|
|
228
|
+
if (drawn > 0) {
|
|
229
|
+
clear_table()
|
|
230
|
+
draw_table()
|
|
231
|
+
}
|
|
232
|
+
return
|
|
233
|
+
}
|
|
234
|
+
# Readiness reaches the cells through the events alone, so without a
|
|
235
|
+
# live table it is the only thing that can move a row.
|
|
236
|
+
if (was_k8s_ready == k8s_ready && was_runtime_ready == runtime_ready) return
|
|
237
|
+
for (i = 1; i <= pod_count; i++) append_row(pods[i])
|
|
238
|
+
}
|
|
239
|
+
# Both phases confirmed is the monitor signing off; the hand-off waits
|
|
240
|
+
# for the report lines of that iteration so the table lands on its final
|
|
241
|
+
# frame first.
|
|
242
|
+
function ready_pending() {
|
|
243
|
+
return events_seen ? (k8s_ready && runtime_ready) : all_pods_running()
|
|
244
|
+
}
|
|
245
|
+
# One report line per pod: "Target pod: NAME | Pod status: X | Runtime status: Y".
|
|
246
|
+
function read_pod_line(line, plain, cell, pod, k8s, runtime) {
|
|
247
|
+
plain = strip(line)
|
|
248
|
+
if (plain !~ /^Target pod: /) return 0
|
|
249
|
+
if (split(plain, cell, / \| /) < 3) return 0
|
|
250
|
+
pod = cell[1]; sub(/^Target pod:[ ]*/, "", pod)
|
|
251
|
+
k8s = cell[2]; sub(/^Pod status:[ ]*/, "", k8s)
|
|
252
|
+
runtime = cell[3]; sub(/^Runtime status:[ ]*/, "", runtime)
|
|
253
|
+
if (pod == "") return 0
|
|
254
|
+
if (is_fatal(runtime)) note_fatal("pod " pod, "runtime status=" runtime)
|
|
255
|
+
if (!(pod in pod_row)) {
|
|
256
|
+
pod_row[pod] = ++pod_count
|
|
257
|
+
pods[pod_count] = pod
|
|
258
|
+
}
|
|
259
|
+
# The report itself is unstamped: the clock is the one the monitor
|
|
260
|
+
# printed for this iteration, so the title advances with the run.
|
|
261
|
+
cycle_time = last_time != "" ? last_time : started
|
|
262
|
+
pod_k8s[pod] = k8s
|
|
263
|
+
pod_runtime[pod] = runtime
|
|
264
|
+
current_pod = pod
|
|
265
|
+
return 1
|
|
266
|
+
}
|
|
267
|
+
# Every pod reporting its expected runtime status with no pending
|
|
268
|
+
# marker is what the deployment itself calls ready. `error` is
|
|
269
|
+
# the fatal value in the RUNTIME_STATUS contract: a terminal state, not a
|
|
270
|
+
# ready one, and reading it as ready handed off to the traffic switch on
|
|
271
|
+
# a deployment that had already failed.
|
|
272
|
+
function all_pods_running( i, pod, runtime) {
|
|
273
|
+
if (pod_count == 0) return 0
|
|
274
|
+
for (i = 1; i <= pod_count; i++) {
|
|
275
|
+
pod = pods[i]
|
|
276
|
+
if (pod_k8s[pod] != "Running") return 0
|
|
277
|
+
runtime = runtime_cell(pod)
|
|
278
|
+
if (runtime == "" || runtime ~ /pending/ || is_fatal(runtime)) return 0
|
|
279
|
+
}
|
|
280
|
+
return 1
|
|
281
|
+
}
|
|
282
|
+
# The bare contract value, not a substring: a phase name that merely
|
|
283
|
+
# contains it (or a log line quoting it) is not a fatal latch.
|
|
284
|
+
function is_fatal(status) {
|
|
285
|
+
return status == "error"
|
|
286
|
+
}
|
|
287
|
+
# Stack frames and source URLs carry absolute host paths and module layout,
|
|
288
|
+
# which must not reach a CI transcript. Both log files still hold them.
|
|
289
|
+
function is_trace(line) {
|
|
290
|
+
return line ~ /^[ \t]*at [^ ]/ || line ~ /file:\/\/\// || line ~ /^[ \t]*at async / || line ~ /^[A-Za-z_]*Error: /
|
|
291
|
+
}
|
|
292
|
+
# Records the fatal latch for run_quiet. A step can report this and still
|
|
293
|
+
# exit 0 — the in-pod lifecycle deliberately does not crash the container
|
|
294
|
+
# — so the exit status alone cannot be trusted to stop the deployment.
|
|
295
|
+
function note_fatal(source, detail) {
|
|
296
|
+
if (fatal_seen) return
|
|
297
|
+
fatal_seen = 1
|
|
298
|
+
printf "%s: %s\n", source, detail > fail_flag
|
|
299
|
+
close(fail_flag)
|
|
300
|
+
}
|
|
301
|
+
# The table stops being a live region here: the deployment is handing
|
|
302
|
+
# over to the traffic switch, so the last frame stays on screen and the
|
|
303
|
+
# chatter the runner prints below it is dropped.
|
|
304
|
+
function hand_off() {
|
|
305
|
+
handed_off = 1
|
|
306
|
+
remaining = 0
|
|
307
|
+
drawn = 0
|
|
308
|
+
last_pod_line = 0
|
|
309
|
+
final_table()
|
|
310
|
+
put(handoff)
|
|
311
|
+
}
|
|
312
|
+
# A later monitor in the same command (a second colour, a rollback) opens
|
|
313
|
+
# its own table below the one that was handed off.
|
|
314
|
+
function reset_table() {
|
|
315
|
+
close_group()
|
|
316
|
+
handed_off = 0
|
|
317
|
+
events_seen = 0
|
|
318
|
+
k8s_ready = 0
|
|
319
|
+
runtime_ready = 0
|
|
320
|
+
pod_count = 0
|
|
321
|
+
cycles = 0
|
|
322
|
+
cycle_time = ""
|
|
323
|
+
appended_header = 0
|
|
324
|
+
appended_cycle = 0
|
|
325
|
+
drawn = 0
|
|
326
|
+
delete pods
|
|
327
|
+
delete pod_row
|
|
328
|
+
delete pod_k8s
|
|
329
|
+
delete pod_runtime
|
|
330
|
+
delete last_row
|
|
331
|
+
}
|
|
332
|
+
# pod_ready is a deployment-wide event: it only annotates a pod whose
|
|
333
|
+
# own phase already agrees, never a stale one still coming up.
|
|
334
|
+
function k8s_cell(pod, cell) {
|
|
335
|
+
cell = pod_k8s[pod]
|
|
336
|
+
return (k8s_ready && cell == "Running") ? cell " (ready)" : cell
|
|
337
|
+
}
|
|
338
|
+
function runtime_cell(pod) {
|
|
339
|
+
return pod_runtime[pod] != "" ? pod_runtime[pod] : last_runtime
|
|
340
|
+
}
|
|
341
|
+
# Columns only ever grow: a cell that shrinks must not reflow the table
|
|
342
|
+
# under the reader between frames.
|
|
343
|
+
function measure( i, pod, over, budget) {
|
|
344
|
+
for (i = 1; i <= pod_count; i++) {
|
|
345
|
+
pod = pods[i]
|
|
346
|
+
if (length(pod) > w_pod) w_pod = length(pod)
|
|
347
|
+
if (length(k8s_cell(pod)) > w_k8s) w_k8s = length(k8s_cell(pod))
|
|
348
|
+
if (length(runtime_cell(pod)) > w_runtime) w_runtime = length(runtime_cell(pod))
|
|
349
|
+
}
|
|
350
|
+
# 10 columns of borders and padding. On a narrow terminal the pod
|
|
351
|
+
# column gives up room first, then the status columns, before fit()
|
|
352
|
+
# starts cutting cells off the right edge.
|
|
353
|
+
w_pod_fit = w_pod
|
|
354
|
+
w_runtime_fit = w_runtime
|
|
355
|
+
w_k8s_fit = w_k8s
|
|
356
|
+
# A streamed table cannot re-pad the rows it already printed, so the
|
|
357
|
+
# status columns start wide enough for the values the monitor is
|
|
358
|
+
# known to report and stop drifting under the header.
|
|
359
|
+
if (!redraw) {
|
|
360
|
+
if (w_k8s_fit < 17) w_k8s_fit = 17
|
|
361
|
+
if (w_runtime_fit < 28) w_runtime_fit = 28
|
|
362
|
+
return
|
|
363
|
+
}
|
|
364
|
+
# fit() cuts the last column, so the row has to land inside it.
|
|
365
|
+
budget = width - 1
|
|
366
|
+
over = row_width() - budget
|
|
367
|
+
if (over > 0) {
|
|
368
|
+
w_pod_fit = w_pod_fit - over < 12 ? 12 : w_pod_fit - over
|
|
369
|
+
over = row_width() - budget
|
|
370
|
+
}
|
|
371
|
+
if (over > 0) {
|
|
372
|
+
w_runtime_fit = w_runtime_fit - over < 16 ? 16 : w_runtime_fit - over
|
|
373
|
+
over = row_width() - budget
|
|
374
|
+
}
|
|
375
|
+
if (over > 0) w_k8s_fit = w_k8s_fit - over < 12 ? 12 : w_k8s_fit - over
|
|
376
|
+
}
|
|
377
|
+
function row_width() {
|
|
378
|
+
return w_pod_fit + w_k8s_fit + w_runtime_fit + 10
|
|
379
|
+
}
|
|
380
|
+
# The iteration and the clock are one per frame, not one per pod: they
|
|
381
|
+
# title the table instead of repeating down two columns of it.
|
|
382
|
+
function title_line() {
|
|
383
|
+
put(paint(sprintf("%s (refresh #%d, %s)", label, cycles,
|
|
384
|
+
cycle_time != "" ? cycle_time : started), "1"))
|
|
385
|
+
}
|
|
386
|
+
function header_lines() {
|
|
387
|
+
put(paint(sprintf("| %s | %s | %s |", pad("POD NAME", w_pod_fit),
|
|
388
|
+
pad("K8S STATUS", w_k8s_fit), pad("RUNTIME STATUS", w_runtime_fit)), "1"))
|
|
389
|
+
put(paint(sprintf("|%s|%s|%s|", rule(w_pod_fit + 2), rule(w_k8s_fit + 2),
|
|
390
|
+
rule(w_runtime_fit + 2)), "2"))
|
|
391
|
+
}
|
|
392
|
+
function pod_line(pod, runtime) {
|
|
393
|
+
runtime = runtime_cell(pod)
|
|
394
|
+
put(sprintf("| %s | %s | %s |",
|
|
395
|
+
paint(pad(trim(pod, w_pod_fit), w_pod_fit), "1"),
|
|
396
|
+
paint(pad(trim(k8s_cell(pod), w_k8s_fit), w_k8s_fit), k8s_ready ? "32" : "33"),
|
|
397
|
+
paint(pad(trim(runtime, w_runtime_fit), w_runtime_fit), (runtime ~ /pending/ || !runtime_ready) ? "36" : "32")))
|
|
398
|
+
}
|
|
399
|
+
function clear_table() {
|
|
400
|
+
if (!redraw || drawn == 0) return
|
|
401
|
+
printf "%s[%dA%s[J", esc, drawn, esc
|
|
402
|
+
drawn = 0
|
|
403
|
+
}
|
|
404
|
+
function draw_table( i) {
|
|
405
|
+
if (!redraw || pod_count == 0) return
|
|
406
|
+
# A table taller than the screen scrolls, and the cursor-up count no
|
|
407
|
+
# longer addresses the rows it drew; degrade to appended rows.
|
|
408
|
+
if (rows > 0 && pod_count + 3 >= rows) {
|
|
409
|
+
redraw = 0
|
|
410
|
+
drawn = 0
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
measure()
|
|
414
|
+
title_line()
|
|
415
|
+
header_lines()
|
|
416
|
+
for (i = 1; i <= pod_count; i++) pod_line(pods[i])
|
|
417
|
+
drawn = pod_count + 3
|
|
418
|
+
}
|
|
419
|
+
# Without a live table a row is only worth printing when its cells
|
|
420
|
+
# actually moved; the iteration count alone is not a change. The title is
|
|
421
|
+
# reprinted whenever a later iteration is the one moving rows, so a
|
|
422
|
+
# streamed row is still dated without carrying its own clock column.
|
|
423
|
+
# The parsing every rendering shares: it advances the monitor'"'"'s event state machine,
|
|
424
|
+
# records what each pod reported, and latches a fatal runtime status. What a line *is*
|
|
425
|
+
# cannot depend on how the run is being displayed, so this answers only that, and the
|
|
426
|
+
# caller decides what to show.
|
|
427
|
+
function track(line) {
|
|
428
|
+
if (in_json) {
|
|
429
|
+
if (line ~ json_close) {
|
|
430
|
+
in_json = 0
|
|
431
|
+
apply_event()
|
|
432
|
+
} else {
|
|
433
|
+
if (json_value("phase") != "") event_phase = json_value("phase")
|
|
434
|
+
if (json_value("state") != "") event_state = json_value("state")
|
|
435
|
+
if (json_value("status") != "") event_status = json_value("status")
|
|
436
|
+
}
|
|
437
|
+
return "event"
|
|
438
|
+
}
|
|
439
|
+
if (line ~ json_open) {
|
|
440
|
+
in_json = 1
|
|
441
|
+
event_phase = event_state = event_status = ""
|
|
442
|
+
return "event"
|
|
443
|
+
}
|
|
444
|
+
return read_pod_line(line) ? "pod" : "other"
|
|
445
|
+
}
|
|
446
|
+
function append_row(pod, cells) {
|
|
447
|
+
if (debug) return
|
|
448
|
+
cells = pod "|" k8s_cell(pod) "|" runtime_cell(pod)
|
|
449
|
+
if (cells == last_row[pod]) return
|
|
450
|
+
last_row[pod] = cells
|
|
451
|
+
measure()
|
|
452
|
+
open_group()
|
|
453
|
+
if (appended_cycle != cycles) {
|
|
454
|
+
title_line()
|
|
455
|
+
appended_cycle = cycles
|
|
456
|
+
}
|
|
457
|
+
if (!appended_header) {
|
|
458
|
+
header_lines()
|
|
459
|
+
appended_header = 1
|
|
460
|
+
}
|
|
461
|
+
pod_line(pod)
|
|
462
|
+
}
|
|
463
|
+
BEGIN {
|
|
464
|
+
w_pod = length("POD NAME")
|
|
465
|
+
w_k8s = length("K8S STATUS")
|
|
466
|
+
w_runtime = length("RUNTIME STATUS")
|
|
467
|
+
group_open = 0
|
|
468
|
+
esc = sprintf("%c", 27)
|
|
469
|
+
esc_seq = esc "\\[[0-9;]*[A-Za-z]"
|
|
470
|
+
clock = "[0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
|
|
471
|
+
json_open = "deploy-monitor:[ ]*[{]"
|
|
472
|
+
json_close = "^[ \t]*[}],?[ \t]*$"
|
|
473
|
+
}
|
|
474
|
+
{
|
|
475
|
+
print > debug_log
|
|
476
|
+
# The monitor stamps its own lines in local time; the ISO field
|
|
477
|
+
# inside an emit is UTC, so it never feeds the column.
|
|
478
|
+
if ($0 !~ /"timestamp"/ && match(strip($0), clock)) last_time = substr(strip($0), RSTART, RLENGTH)
|
|
479
|
+
}
|
|
480
|
+
{
|
|
481
|
+
# DEBUG streams the step verbatim: no table, no group, no passthrough window, and no
|
|
482
|
+
# dropped stack traces — a CI transcript withholds those because it is published,
|
|
483
|
+
# which is not true of the session an operator opened to audit this run. Tracking
|
|
484
|
+
# still runs, so a fatal runtime status latches here exactly as in every other mode
|
|
485
|
+
# and a step that reports one still fails.
|
|
486
|
+
if (debug) {
|
|
487
|
+
track($0)
|
|
488
|
+
put($0)
|
|
489
|
+
next
|
|
490
|
+
}
|
|
491
|
+
if (!handed_off && $0 !~ pattern && ready_pending()) hand_off()
|
|
492
|
+
if (handed_off) {
|
|
493
|
+
if ($0 !~ pattern) next
|
|
494
|
+
reset_table()
|
|
495
|
+
}
|
|
496
|
+
line_kind = track($0)
|
|
497
|
+
# The monitor JSON is state already carried by the table cells: it is
|
|
498
|
+
# consumed here and never reaches the terminal.
|
|
499
|
+
if (line_kind == "event") {
|
|
500
|
+
if (remaining > 0) remaining--
|
|
501
|
+
last_pod_line = 0
|
|
502
|
+
next
|
|
503
|
+
}
|
|
504
|
+
if (line_kind == "pod") {
|
|
505
|
+
# Pod reports arrive back to back, one per pod, once per monitor
|
|
506
|
+
# iteration: the first of a run opens a new cycle.
|
|
507
|
+
if (!last_pod_line) cycles++
|
|
508
|
+
last_pod_line = 1
|
|
509
|
+
remaining = lines_after + 1
|
|
510
|
+
if (redraw) {
|
|
511
|
+
clear_table()
|
|
512
|
+
draw_table()
|
|
513
|
+
}
|
|
514
|
+
if (!redraw) append_row(current_pod)
|
|
515
|
+
next
|
|
516
|
+
}
|
|
517
|
+
last_pod_line = 0
|
|
518
|
+
if ($0 ~ pattern) remaining = lines_after + 1
|
|
519
|
+
if (remaining > 0) {
|
|
520
|
+
if (is_trace($0)) {
|
|
521
|
+
remaining--
|
|
522
|
+
next
|
|
523
|
+
}
|
|
524
|
+
clear_table()
|
|
525
|
+
close_group()
|
|
526
|
+
put($0)
|
|
527
|
+
remaining--
|
|
528
|
+
draw_table()
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
END {
|
|
532
|
+
if (!debug && !handed_off && ready_pending()) hand_off()
|
|
533
|
+
close_group()
|
|
534
|
+
}
|
|
535
|
+
' <"$fifo_dir/merged" &
|
|
536
|
+
filter_pid=$!
|
|
537
|
+
|
|
538
|
+
# stderr is duplicated: on its own for the native error and stack trace, and
|
|
539
|
+
# into the merged stream so both the debug log and the filter see it in
|
|
540
|
+
# chronological order with stdout.
|
|
541
|
+
tee -a "$error_log" <"$fifo_dir/stderr" >"$fifo_dir/merged" &
|
|
542
|
+
stderr_pid=$!
|
|
543
|
+
|
|
544
|
+
"$@" >"$fifo_dir/merged" 2>"$fifo_dir/stderr" || status=$?
|
|
545
|
+
|
|
546
|
+
# Drain both readers before the paths are printed, or the trace can still be
|
|
547
|
+
# in flight. Bounded: a command that leaks a child holding a stream open must
|
|
548
|
+
# not hang the deployment, and by then everything read has been written.
|
|
549
|
+
run_quiet_drain "$stderr_pid"
|
|
550
|
+
run_quiet_drain "$filter_pid"
|
|
551
|
+
rm -rf "$fifo_dir"
|
|
552
|
+
|
|
553
|
+
# A deployment can fail without the command failing. The in-pod lifecycle latches
|
|
554
|
+
# `container-status=error` and deliberately does not crash the container, so a step that
|
|
555
|
+
# reported a fatal runtime state can still exit 0 — and a green step here is a green
|
|
556
|
+
# GitHub Actions job on a deployment that never came up. The latch the filter recorded is
|
|
557
|
+
# therefore promoted to a failure exit of its own.
|
|
558
|
+
fatal=$(cat "$fail_flag" 2>/dev/null) || true
|
|
559
|
+
rm -f "$fail_flag"
|
|
560
|
+
if [ "$status" -eq 0 ] && [ -n "$fatal" ]; then
|
|
561
|
+
status=1
|
|
562
|
+
printf -- '--- fatal runtime latch ---\n%s\n' "$fatal" >>"$error_log"
|
|
563
|
+
printf '%s✖ %s reported a fatal runtime state but exited 0%s\n' \
|
|
564
|
+
"$RUN_QUIET_RED" "$label" "$RUN_QUIET_RESET" >&2
|
|
565
|
+
fi
|
|
566
|
+
|
|
567
|
+
if [ "$status" -ne 0 ]; then
|
|
568
|
+
run_quiet_error_trace "$debug_log" "$error_log"
|
|
569
|
+
printf '%s✖ %s failed (exit %s)%s\n' "$RUN_QUIET_RED" "$label" "$status" "$RUN_QUIET_RESET" >&2
|
|
570
|
+
printf '%s error trace: %s\n debug log: %s%s\n' \
|
|
571
|
+
"$RUN_QUIET_RED" "$error_log" "$debug_log" "$RUN_QUIET_RESET" >&2
|
|
572
|
+
return "$status"
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
rm -f "$debug_log" "$error_log"
|
|
576
|
+
|
|
577
|
+
return "$status"
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
# Appends the failing part of the merged log to the error trace, so the trace ends
|
|
581
|
+
# with the error rather than with whatever last wrote to stderr. Cuts from the first
|
|
582
|
+
# error marker; with no marker the tail stands in, which is where a logger-only
|
|
583
|
+
# failure reports itself.
|
|
584
|
+
run_quiet_error_trace() {
|
|
585
|
+
local debug_log="$1"
|
|
586
|
+
local error_log="$2"
|
|
587
|
+
local tail_lines="${3:-40}"
|
|
588
|
+
local first
|
|
589
|
+
|
|
590
|
+
# grep exits 1 when it matches nothing, and every deploy script runs under `set -e` with
|
|
591
|
+
# `pipefail`: unguarded, a failing step whose log carries no marker aborted this function
|
|
592
|
+
# before run_quiet could print the exit code and the two log paths, and the tail fallback
|
|
593
|
+
# below was unreachable. The no-match case is the fallback's trigger, not an error.
|
|
594
|
+
first=$(grep -a -n -m1 -E 'Error:|Error \[|^[[:space:]]+at |✖' "$debug_log" 2>/dev/null | cut -d: -f1) || true
|
|
595
|
+
|
|
596
|
+
printf -- '--- error trace (from merged log) ---\n' >>"$error_log"
|
|
597
|
+
if [ -n "$first" ]; then
|
|
598
|
+
tail -n "+$first" "$debug_log" >>"$error_log"
|
|
599
|
+
else
|
|
600
|
+
tail -n "$tail_lines" "$debug_log" >>"$error_log"
|
|
601
|
+
fi
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
run_quiet_drain() {
|
|
605
|
+
local pid="$1"
|
|
606
|
+
|
|
607
|
+
timeout 10 tail --pid="$pid" -f /dev/null 2>/dev/null || true
|
|
608
|
+
kill "$pid" 2>/dev/null || true
|
|
609
|
+
wait "$pid" 2>/dev/null || true
|
|
610
|
+
}
|