@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/cluster.js
CHANGED
|
@@ -4,26 +4,31 @@
|
|
|
4
4
|
* @namespace UnderpostCluster
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { clusterTypeFactory, gatewayApiEnabledFactory, resolveReplicaCount } from '../server/conf.js';
|
|
8
|
-
import { getNpmRootPath, HOST_VOLUME_ROOT } from '../server/environment.js';
|
|
9
|
-
import { loggerFactory } from '../server/logger.js';
|
|
10
|
-
import { shellExec } from '../server/process.js';
|
|
11
|
-
import { crictlCommandFactory, resolveCriSocket } from '../server/cri.js';
|
|
7
|
+
import { clusterTypeFactory, gatewayApiEnabledFactory, resolveReplicaCount } from '../server/runtime/conf.js';
|
|
8
|
+
import { getNpmRootPath, HOST_VOLUME_ROOT } from '../server/runtime/environment.js';
|
|
9
|
+
import { loggerFactory } from '../server/ops/logger.js';
|
|
10
|
+
import { shellExec } from '../server/runtime/process.js';
|
|
11
|
+
import { crictlCommandFactory, resolveCriSocket } from '../server/ops/cri.js';
|
|
12
12
|
import {
|
|
13
13
|
runSELinuxCommands,
|
|
14
|
-
selinuxContainerSharedContextCommandsFactory,
|
|
15
14
|
selinuxEnforcingCommandsFactory,
|
|
16
15
|
selinuxPackagesCommandFactory,
|
|
17
16
|
selinuxRestoreconCommandFactory,
|
|
18
|
-
} from '../server/selinux.js';
|
|
19
|
-
import
|
|
17
|
+
} from '../server/security/selinux.js';
|
|
18
|
+
import ContainerStorageService, {
|
|
19
|
+
containerStorageRootsFactory,
|
|
20
|
+
ensureContainerStorage,
|
|
21
|
+
localPathConfigCommandFactory,
|
|
22
|
+
localPathRootsFactory,
|
|
23
|
+
} from '../server/security/container-storage.js';
|
|
24
|
+
import { UNDERPOST_GATEWAY, seedDefaultStatusPage } from '../server/network/underpost-gateway.js';
|
|
20
25
|
import {
|
|
21
26
|
UNDERPOST_INGRESS,
|
|
22
27
|
gatewayBackendFactory,
|
|
23
28
|
underpostIngressConfFactory,
|
|
24
29
|
underpostIngressHostMapFactory,
|
|
25
30
|
underpostIngressManifestsFactory,
|
|
26
|
-
} from '../server/underpost-ingress.js';
|
|
31
|
+
} from '../server/network/underpost-ingress.js';
|
|
27
32
|
import { MONGODB_DEFAULT_REPLICA_COUNT } from '../db/mongo/MongooseDB.js';
|
|
28
33
|
import { MongoBootstrap } from '../db/mongo/MongoBootstrap.js';
|
|
29
34
|
import os from 'os';
|
|
@@ -35,8 +40,8 @@ const logger = loggerFactory(import.meta);
|
|
|
35
40
|
const GATEWAY_API_RELEASE = 'v1.5.1';
|
|
36
41
|
const ENVOY_GATEWAY_VERSION = 'v1.8.3';
|
|
37
42
|
const CONTOUR_NAMESPACE = 'projectcontour';
|
|
38
|
-
const
|
|
39
|
-
|
|
43
|
+
const LOCAL_PATH_PROVISIONER_MANIFEST =
|
|
44
|
+
'https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml';
|
|
40
45
|
const K3S_SELINUX_PATHS = [
|
|
41
46
|
'/usr/local/bin/k3s',
|
|
42
47
|
'/etc/rancher',
|
|
@@ -45,15 +50,16 @@ const K3S_SELINUX_PATHS = [
|
|
|
45
50
|
'/var/lib/cni',
|
|
46
51
|
];
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const enforceSELinux = (paths = []) => {
|
|
53
|
+
// `semanage` and `restorecon` come from separate packages and neither is guaranteed on a minimal
|
|
54
|
+
// Rocky install. Installed before anything tries to register a mapping, because a missing
|
|
55
|
+
// `semanage` would otherwise turn every persistent labeling command into a hard failure.
|
|
56
|
+
const ensureSELinuxTooling = () =>
|
|
54
57
|
shellExec(
|
|
55
58
|
`if [ -f /etc/redhat-release ] && command -v dnf >/dev/null 2>&1 && { ! command -v restorecon >/dev/null 2>&1 || ! command -v semanage >/dev/null 2>&1; }; then ${selinuxPackagesCommandFactory()}; fi`,
|
|
56
59
|
);
|
|
60
|
+
|
|
61
|
+
const enforceSELinux = (paths = []) => {
|
|
62
|
+
ensureSELinuxTooling();
|
|
57
63
|
const commands = selinuxEnforcingCommandsFactory({ restorePaths: paths });
|
|
58
64
|
runSELinuxCommands(commands, { execute: shellExec });
|
|
59
65
|
};
|
|
@@ -112,9 +118,10 @@ class UnderpostCluster {
|
|
|
112
118
|
* @param {boolean} [options.nodePort=false] - Expose enabled ready services (e.g. MongoDB 4.4, Valkey)
|
|
113
119
|
* to the host/public network via their NodePort Service manifest. The node port value lives directly
|
|
114
120
|
* in each manifest (mongodb-4.4/mongodb-nodeport.yaml, valkey/valkey-nodeport.yaml).
|
|
115
|
-
* @param {string} [options.
|
|
116
|
-
* to a specific Kubernetes node by name (e.g.
|
|
117
|
-
* `kubernetes.io/hostname` nodeSelector patch once
|
|
121
|
+
* @param {string} [options.nodeName=''] - Pin the just-deployed StatefulSet (MongoDB 4.4 / Valkey)
|
|
122
|
+
* and the observability workloads to a specific Kubernetes node by name (e.g.
|
|
123
|
+
* 'localhost.localdomain'). Applied via a `kubernetes.io/hostname` nodeSelector patch once
|
|
124
|
+
* the workload reports Ready.
|
|
118
125
|
* @memberof UnderpostCluster
|
|
119
126
|
*/
|
|
120
127
|
async init(
|
|
@@ -154,7 +161,7 @@ class UnderpostCluster {
|
|
|
154
161
|
hosts: '',
|
|
155
162
|
replicas: '',
|
|
156
163
|
nodePort: false,
|
|
157
|
-
|
|
164
|
+
nodeName: '',
|
|
158
165
|
},
|
|
159
166
|
) {
|
|
160
167
|
if (options.initHost) return Underpost.cluster.initHost();
|
|
@@ -232,6 +239,12 @@ class UnderpostCluster {
|
|
|
232
239
|
logger.info(
|
|
233
240
|
`Detected existing ${runtime.type} cluster (${runtime.ready ? 'Ready' : 'NotReady'}); skipping initialization.`,
|
|
234
241
|
);
|
|
242
|
+
// Initialization is skipped, but the labeling invariant is not: the node directories
|
|
243
|
+
// backing PersistentVolumes outlive the bring-up that created them, and a policy update,
|
|
244
|
+
// a full relabel or a directory recreated by kubelet resets them to the policy default.
|
|
245
|
+
// Re-asserting it costs a `semanage` lookup and a `restorecon` pass, mutates no workload,
|
|
246
|
+
// and never changes SELinux mode.
|
|
247
|
+
Underpost.cluster.ensureContainerStorageContexts();
|
|
235
248
|
}
|
|
236
249
|
|
|
237
250
|
// --- Kubeadm/Kind/K3s Cluster Initialization ---
|
|
@@ -265,7 +278,7 @@ class UnderpostCluster {
|
|
|
265
278
|
} else if (options.kubeadm) {
|
|
266
279
|
Underpost.cluster.config();
|
|
267
280
|
Underpost.cluster.natSetup({ underpostRoot });
|
|
268
|
-
|
|
281
|
+
Underpost.cluster.ensureContainerStorageContexts({ controlPlane: true });
|
|
269
282
|
logger.info('Initializing Kubeadm control plane...');
|
|
270
283
|
// Set default values if not provided
|
|
271
284
|
const podNetworkCidr = options.podNetworkCidr || '192.168.0.0/16';
|
|
@@ -293,18 +306,13 @@ class UnderpostCluster {
|
|
|
293
306
|
// Untaint control plane node to allow scheduling pods
|
|
294
307
|
const nodeName = os.hostname();
|
|
295
308
|
shellExec(`kubectl taint nodes ${nodeName} node-role.kubernetes.io/control-plane:NoSchedule-`);
|
|
296
|
-
// Install local-path-provisioner for dynamic PVCs
|
|
297
|
-
logger.info('Installing local-path-provisioner...');
|
|
298
|
-
shellExec(
|
|
299
|
-
`kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml`,
|
|
300
|
-
);
|
|
301
|
-
|
|
302
309
|
// The CNI lands asynchronously, and the node stays NotReady until it
|
|
303
310
|
// does. Block here so the deploy steps that follow (MongoDB and the
|
|
304
311
|
// application workloads) schedule onto a node that can actually run
|
|
305
312
|
// them, instead of racing the Calico rollout.
|
|
306
313
|
logger.info('Waiting for the node to become Ready (Calico rollout)...');
|
|
307
314
|
shellExec(`kubectl wait --for=condition=Ready node --all --timeout=300s`);
|
|
315
|
+
Underpost.cluster.ensureLocalPathProvisioner();
|
|
308
316
|
} else {
|
|
309
317
|
Underpost.cluster.config();
|
|
310
318
|
Underpost.cluster.natSetup({ underpostRoot });
|
|
@@ -355,36 +363,19 @@ class UnderpostCluster {
|
|
|
355
363
|
shellExec(`node ${underpostRoot}/bin/deploy kubeflow-spark-operator${options.kubeadm ? ' kubeadm' : ''}`);
|
|
356
364
|
}
|
|
357
365
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (options.prom) {
|
|
372
|
-
shellExec(`kubectl delete deployment prometheus --ignore-not-found`);
|
|
373
|
-
shellExec(`kubectl delete configmap prometheus-config --ignore-not-found`);
|
|
374
|
-
shellExec(`kubectl delete service prometheus --ignore-not-found`);
|
|
375
|
-
// Prometheus server host: http://<prometheus-cluster-ip>:9090
|
|
376
|
-
const yaml = `${fs.readFileSync(`${underpostRoot}/manifests/prometheus/deployment.yaml`, 'utf8').replace(
|
|
377
|
-
'- targets: []',
|
|
378
|
-
`- targets: [${options.prom
|
|
379
|
-
.split(',')
|
|
380
|
-
.map((host) => `'${host}'`)
|
|
381
|
-
.join(',')}]`,
|
|
382
|
-
)}`;
|
|
383
|
-
console.log(yaml);
|
|
384
|
-
shellExec(`kubectl apply -f - -n ${options.namespace} <<'EOF'
|
|
385
|
-
${yaml}
|
|
386
|
-
EOF
|
|
387
|
-
`);
|
|
366
|
+
// Grafana and Prometheus are two faces of one stack, so either flag
|
|
367
|
+
// converges the whole of it — including Alertmanager and the Blackbox
|
|
368
|
+
// Exporter, which the alert rules and probes are useless without. The
|
|
369
|
+
// scrape configuration is rendered from the deploy configuration and the
|
|
370
|
+
// event registry by the monitor CLI; `--prom [hosts]` only adds hosts
|
|
371
|
+
// that configuration does not name.
|
|
372
|
+
if (options.grafana || options.prom) {
|
|
373
|
+
await Underpost.monitor.deployObservability({
|
|
374
|
+
namespace: options.namespace,
|
|
375
|
+
dev: options.dev,
|
|
376
|
+
nodeName: options.nodeName,
|
|
377
|
+
hosts: typeof options.prom === 'string' ? options.prom : options.hosts,
|
|
378
|
+
});
|
|
388
379
|
}
|
|
389
380
|
|
|
390
381
|
if (options.valkey) {
|
|
@@ -396,11 +387,11 @@ EOF
|
|
|
396
387
|
// The node port (32079) is set directly in the manifest.
|
|
397
388
|
if (valkeyReady && options.nodePort)
|
|
398
389
|
shellExec(`kubectl apply -f ${underpostRoot}/manifests/valkey/valkey-nodeport.yaml -n ${options.namespace}`);
|
|
399
|
-
if (valkeyReady && options.
|
|
390
|
+
if (valkeyReady && options.nodeName)
|
|
400
391
|
Underpost.cluster.pinToNode({
|
|
401
392
|
name: 'valkey-service',
|
|
402
393
|
namespace: options.namespace,
|
|
403
|
-
node: options.
|
|
394
|
+
node: options.nodeName,
|
|
404
395
|
});
|
|
405
396
|
if (valkeyReady && serviceHost)
|
|
406
397
|
Underpost.cluster.syncServiceConnectionEnv({
|
|
@@ -417,32 +408,32 @@ EOF
|
|
|
417
408
|
// Encrypted store first; when no manifest exists the secret is seeded from its origin
|
|
418
409
|
// seed path below. A manifest that exists but fails validation raises rather than
|
|
419
410
|
// silently seeding stale credentials.
|
|
420
|
-
if (!Underpost.secret.
|
|
421
|
-
|
|
422
|
-
`sudo kubectl create secret generic mariadb-secret --from-file=username=/home/dd/engine/engine-private/mariadb-username --from-file=password=/home/dd/engine/engine-private/mariadb-password --dry-run=client -o yaml | kubectl apply -f - -n ${options.namespace}`,
|
|
423
|
-
);
|
|
411
|
+
if (!Underpost.secret.applyIfPresent('mariadb-secret', options.namespace))
|
|
412
|
+
Underpost.secret.applyFromOriginSeed('mariadb-secret', options.namespace);
|
|
424
413
|
shellExec(`kubectl delete statefulset mariadb-statefulset -n ${options.namespace} --ignore-not-found`);
|
|
425
414
|
|
|
426
415
|
if (options.pullImage) Underpost.cluster.pullImage('mariadb:latest', options);
|
|
416
|
+
// The StatefulSet's volumeClaimTemplate is dynamically provisioned, so the data lands in
|
|
417
|
+
// a subdirectory of the local-path root and inherits that root's label.
|
|
418
|
+
Underpost.cluster.ensureContainerStorageContexts({ extraPaths: ['/data/mariadb'] });
|
|
427
419
|
shellExec(`kubectl apply -f ${underpostRoot}/manifests/mariadb/storage-class.yaml -n ${options.namespace}`);
|
|
428
420
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mariadb -n ${options.namespace}`);
|
|
429
421
|
}
|
|
430
422
|
if (options.mysql) {
|
|
431
|
-
if (!Underpost.secret.
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
423
|
+
if (!Underpost.secret.applyIfPresent('mysql-secret', options.namespace))
|
|
424
|
+
Underpost.secret.applyFromOriginSeed('mysql-secret', options.namespace);
|
|
425
|
+
// The data directory is prepared, not opened up: a world-writable host path plus the
|
|
426
|
+
// operator's ownership was standing in for the SELinux label the container actually
|
|
427
|
+
// needed. `container_file_t` is what lets mysqld write here; 0755 root-owned is enough,
|
|
428
|
+
// because the image's entrypoint chowns the tree to its own uid on first start.
|
|
429
|
+
Underpost.cluster.ensureContainerStorageContexts({ extraPaths: ['/data/mysql'] });
|
|
438
430
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/mysql -n ${options.namespace}`);
|
|
439
431
|
}
|
|
440
432
|
if (options.postgresql) {
|
|
441
433
|
if (options.pullImage) Underpost.cluster.pullImage('postgres:latest', options);
|
|
442
|
-
if (!Underpost.secret.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
);
|
|
434
|
+
if (!Underpost.secret.applyIfPresent('postgres-secret', options.namespace))
|
|
435
|
+
Underpost.secret.applyFromOriginSeed('postgres-secret', options.namespace);
|
|
436
|
+
Underpost.cluster.ensureContainerStorageContexts({ extraPaths: ['/data/postgresql'] });
|
|
446
437
|
shellExec(`kubectl apply -k ${underpostRoot}/manifests/postgresql -n ${options.namespace}`);
|
|
447
438
|
}
|
|
448
439
|
if (options.mongodb4) {
|
|
@@ -486,11 +477,11 @@ EOF
|
|
|
486
477
|
shellExec(
|
|
487
478
|
`kubectl apply -f ${underpostRoot}/manifests/mongodb-4.4/mongodb-nodeport.yaml -n ${options.namespace}`,
|
|
488
479
|
);
|
|
489
|
-
if (options.
|
|
480
|
+
if (options.nodeName)
|
|
490
481
|
Underpost.cluster.pinToNode({
|
|
491
482
|
name: statefulSetName,
|
|
492
483
|
namespace: options.namespace,
|
|
493
|
-
node: options.
|
|
484
|
+
node: options.nodeName,
|
|
494
485
|
});
|
|
495
486
|
if (serviceHost)
|
|
496
487
|
Underpost.cluster.syncServiceConnectionEnv({
|
|
@@ -724,13 +715,107 @@ EOF
|
|
|
724
715
|
return { type, ready, nodes };
|
|
725
716
|
},
|
|
726
717
|
|
|
718
|
+
/**
|
|
719
|
+
* @method discoverLocalPathRoots
|
|
720
|
+
* @description Reads the node directories the local-path provisioner writes into, from its
|
|
721
|
+
* live ConfigMap. Every dynamically provisioned claim in this platform (Grafana, Prometheus,
|
|
722
|
+
* Alertmanager, IPFS, MariaDB) becomes a subdirectory of one of them, so the root has to be
|
|
723
|
+
* discovered rather than assumed — a wrong guess leaves those claims carrying the `/opt`
|
|
724
|
+
* policy default (`usr_t`), which no `container_t` pod can write.
|
|
725
|
+
* @returns {string[]} Configured node paths; empty when no provisioner is reachable.
|
|
726
|
+
* @memberof UnderpostCluster
|
|
727
|
+
*/
|
|
728
|
+
discoverLocalPathRoots() {
|
|
729
|
+
for (const namespace of ContainerStorageService.LOCAL_PATH_NAMESPACES) {
|
|
730
|
+
const config = `${
|
|
731
|
+
shellExec(localPathConfigCommandFactory({ namespace }), {
|
|
732
|
+
stdout: true,
|
|
733
|
+
silent: true,
|
|
734
|
+
silentOnError: true,
|
|
735
|
+
disableLog: true,
|
|
736
|
+
}) || ''
|
|
737
|
+
}`.trim();
|
|
738
|
+
const roots = localPathRootsFactory(config);
|
|
739
|
+
if (roots.length > 0) return roots;
|
|
740
|
+
}
|
|
741
|
+
return [];
|
|
742
|
+
},
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* @method ensureContainerStorageContexts
|
|
746
|
+
* @description Makes SELinux compatibility an invariant of the storage lifecycle rather than
|
|
747
|
+
* a one-time bring-up step: creates the node directories this platform hands to containers
|
|
748
|
+
* (only when missing, so live data trees keep their ownership and mode), registers the
|
|
749
|
+
* persistent `container_file_t` mapping for each, and restores the trees.
|
|
750
|
+
*
|
|
751
|
+
* Idempotent and safe to call on every deploy. Never relabels paths outside the discovered
|
|
752
|
+
* set, and never changes SELinux mode.
|
|
753
|
+
* @param {object} [options]
|
|
754
|
+
* @param {boolean} [options.controlPlane=false] - Also cover the kubeadm control-plane trees
|
|
755
|
+
* bind-mounted into containers (`/etc/kubernetes`, `/var/lib/etcd`, `/var/lib/calico`).
|
|
756
|
+
* @param {string[]} [options.extraPaths=[]] - Additional node directories to include.
|
|
757
|
+
* @returns {string[]} The roots that were prepared.
|
|
758
|
+
* @memberof UnderpostCluster
|
|
759
|
+
*/
|
|
760
|
+
ensureContainerStorageContexts(options = {}) {
|
|
761
|
+
const roots = containerStorageRootsFactory({
|
|
762
|
+
localPathRoots: Underpost.cluster.discoverLocalPathRoots(),
|
|
763
|
+
extraPaths: options.extraPaths || [],
|
|
764
|
+
controlPlane: options.controlPlane === true,
|
|
765
|
+
});
|
|
766
|
+
logger.info('Preparing container-mounted host storage', { roots });
|
|
767
|
+
// HOST_VOLUME_ROOT is the one root the deploy flow writes into unprivileged (it lives in the
|
|
768
|
+
// operator's home tree and receives each hostPath volume's contents), so it is created owned
|
|
769
|
+
// by the invoking user. The rest stay root-owned: their subdirectories are chowned by each
|
|
770
|
+
// workload's own init container, which is the single owner of that concern.
|
|
771
|
+
const { uid, gid } = os.userInfo();
|
|
772
|
+
const operatorRoots = roots.filter((root) => root === HOST_VOLUME_ROOT);
|
|
773
|
+
const systemRoots = roots.filter((root) => root !== HOST_VOLUME_ROOT);
|
|
774
|
+
if (systemRoots.length > 0) ensureContainerStorage(systemRoots, { execute: shellExec });
|
|
775
|
+
if (operatorRoots.length > 0)
|
|
776
|
+
ensureContainerStorage(operatorRoots, { execute: shellExec, owner: `${uid}:${gid}` });
|
|
777
|
+
return roots;
|
|
778
|
+
},
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* @method ensureLocalPathProvisioner
|
|
782
|
+
* @description Ensures dynamic local-path PVC provisioning is available.
|
|
783
|
+
* @returns {string} Namespace containing the ready provisioner.
|
|
784
|
+
* @memberof UnderpostCluster
|
|
785
|
+
*/
|
|
786
|
+
ensureLocalPathProvisioner() {
|
|
787
|
+
const locations = ['local-path-storage', 'kube-system'];
|
|
788
|
+
let namespace = locations.find((candidate) =>
|
|
789
|
+
`${
|
|
790
|
+
shellExec(`kubectl get deployment local-path-provisioner -n ${candidate} -o name`, {
|
|
791
|
+
stdout: true,
|
|
792
|
+
silent: true,
|
|
793
|
+
silentOnError: true,
|
|
794
|
+
disableLog: true,
|
|
795
|
+
}) || ''
|
|
796
|
+
}`.trim(),
|
|
797
|
+
);
|
|
798
|
+
|
|
799
|
+
if (!namespace) {
|
|
800
|
+
logger.info('Installing local-path-provisioner');
|
|
801
|
+
shellExec(`kubectl apply -f ${LOCAL_PATH_PROVISIONER_MANIFEST}`);
|
|
802
|
+
namespace = 'local-path-storage';
|
|
803
|
+
}
|
|
804
|
+
shellExec(`kubectl rollout status deployment/local-path-provisioner -n ${namespace} --timeout=5m`);
|
|
805
|
+
// The provisioner's root exists (or is about to) only now, and its helper pod creates each
|
|
806
|
+
// claim directory by inheriting that root's label. Prepare it here so the first dynamically
|
|
807
|
+
// provisioned claim already lands on `container_file_t` instead of `/opt`'s `usr_t`.
|
|
808
|
+
Underpost.cluster.ensureContainerStorageContexts();
|
|
809
|
+
return namespace;
|
|
810
|
+
},
|
|
811
|
+
|
|
727
812
|
/**
|
|
728
813
|
* @method pinToNode
|
|
729
814
|
* @description Pins a workload to a specific Kubernetes node by patching its
|
|
730
815
|
* pod template with a `kubernetes.io/hostname` nodeSelector. General-purpose;
|
|
731
|
-
* currently used to place the MongoDB 4.4 / Valkey StatefulSets
|
|
732
|
-
* node (`--node-
|
|
733
|
-
* target node.
|
|
816
|
+
* currently used to place the MongoDB 4.4 / Valkey StatefulSets and the
|
|
817
|
+
* observability Deployments on a chosen node (`--node-name`). The patch
|
|
818
|
+
* triggers a rolling reschedule onto the target node.
|
|
734
819
|
* @param {object} params
|
|
735
820
|
* @param {string} [params.kind='statefulset'] - Workload kind to patch.
|
|
736
821
|
* @param {string} params.name - Workload name.
|
|
@@ -1383,6 +1468,16 @@ EOF
|
|
|
1383
1468
|
config(options = { underpostRoot: '.' }) {
|
|
1384
1469
|
const { underpostRoot } = options;
|
|
1385
1470
|
console.log('Applying host configuration: SELinux, Docker, Containerd, and Sysctl settings.');
|
|
1471
|
+
// Label before enforcing, never after: flipping the mode first would put the host into
|
|
1472
|
+
// Enforcing with the storage trees still carrying the policy default, and every pod that
|
|
1473
|
+
// mounts one would start failing for real instead of only logging a denial.
|
|
1474
|
+
//
|
|
1475
|
+
// Registered on every run, not only at first cluster creation: the node directories backing
|
|
1476
|
+
// PersistentVolumes are recreated by resets, by `DirectoryOrCreate`, and by the local-path
|
|
1477
|
+
// helper pod long after `kubeadm init` ran, and each of those inherits the policy default
|
|
1478
|
+
// unless the mapping is already in the store.
|
|
1479
|
+
ensureSELinuxTooling();
|
|
1480
|
+
Underpost.cluster.ensureContainerStorageContexts();
|
|
1386
1481
|
enforceSELinux(['/var/lib/kubelet', '/var/lib/containerd']);
|
|
1387
1482
|
|
|
1388
1483
|
// Enable and start Docker and Kubelet services
|
|
@@ -1439,8 +1534,11 @@ EOF
|
|
|
1439
1534
|
// forever (the upstream unit ships TimeoutStartSec=0).
|
|
1440
1535
|
shellExec(`if systemctl is-active --quiet firewalld; then sudo systemctl disable --now firewalld; fi`);
|
|
1441
1536
|
|
|
1537
|
+
// Storage labeling precedes the Enforcing flip, so the mode is never activated over trees
|
|
1538
|
+
// that still carry the policy default.
|
|
1539
|
+
ensureSELinuxTooling();
|
|
1540
|
+
Underpost.cluster.ensureContainerStorageContexts();
|
|
1442
1541
|
enforceSELinux(K3S_SELINUX_PATHS);
|
|
1443
|
-
shareWithContainers(HOST_VOLUME_PATHS);
|
|
1444
1542
|
|
|
1445
1543
|
// Disable swap. `swapoff -a` is a no-op without swap; the sed only edits
|
|
1446
1544
|
// fstab when a swap line is present.
|
|
@@ -1714,6 +1812,10 @@ fi`);
|
|
|
1714
1812
|
else logger.info(' -> Skipping (pass --remove-volume-host-paths to enable).');
|
|
1715
1813
|
|
|
1716
1814
|
logger.info('Phase 2/7: Enforcing SELinux and restoring runtime contexts...');
|
|
1815
|
+
// The hostPath cleanup above emptied the volume trees; re-asserting the mapping here means
|
|
1816
|
+
// a rebuild starts from correctly labeled storage instead of inheriting the policy default.
|
|
1817
|
+
ensureSELinuxTooling();
|
|
1818
|
+
Underpost.cluster.ensureContainerStorageContexts();
|
|
1717
1819
|
enforceSELinux(['/var/lib/kubelet', '/var/lib/containerd']);
|
|
1718
1820
|
|
|
1719
1821
|
logger.info('Phase 3/7: Stopping host kubelet and container runtimes (kubeadm-scope only)...');
|
|
@@ -1916,7 +2018,7 @@ EOF`);
|
|
|
1916
2018
|
|
|
1917
2019
|
// SOPS and Age for Git-native encrypted secret manifests. Owned by UnderpostSecret so the
|
|
1918
2020
|
// same idempotent install backs `underpost secret --install-tools`.
|
|
1919
|
-
Underpost.secret.
|
|
2021
|
+
Underpost.secret.installTooling();
|
|
1920
2022
|
|
|
1921
2023
|
// Install snap
|
|
1922
2024
|
shellExec(`sudo yum install -y snapd`);
|