@underpostnet/cyberia 3.2.80

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.
Files changed (821) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.example +144 -0
  3. package/.github/workflows/cyberia-client.cd.yml +40 -0
  4. package/.github/workflows/cyberia-server.cd.yml +40 -0
  5. package/.github/workflows/docker-image.cyberia-client.ci.yml +71 -0
  6. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +70 -0
  7. package/.github/workflows/docker-image.cyberia-server.ci.yml +71 -0
  8. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +71 -0
  9. package/.github/workflows/docker-image.engine-cyberia.ci.yml +53 -0
  10. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +53 -0
  11. package/.github/workflows/engine-cyberia.cd.yml +157 -0
  12. package/.github/workflows/engine-cyberia.ci.yml +125 -0
  13. package/.github/workflows/ghpkg.ci.yml +160 -0
  14. package/.github/workflows/gitlab.ci.yml +20 -0
  15. package/.github/workflows/hardhat.ci.yml +82 -0
  16. package/.github/workflows/npmpkg.ci.yml +126 -0
  17. package/.github/workflows/publish.ci.yml +87 -0
  18. package/.github/workflows/publish.cyberia.ci.yml +79 -0
  19. package/.github/workflows/pwa-microservices-template-page.cd.yml +65 -0
  20. package/.github/workflows/pwa-microservices-template-test.ci.yml +33 -0
  21. package/.github/workflows/release.cd.yml +46 -0
  22. package/.nycrc +9 -0
  23. package/.prettierignore +12 -0
  24. package/.prettierrc +9 -0
  25. package/.vscode/extensions.json +10 -0
  26. package/.vscode/settings.json +26 -0
  27. package/CHANGELOG.md +2516 -0
  28. package/CLI-HELP.md +1099 -0
  29. package/Dockerfile +161 -0
  30. package/Dockerfile.dev +161 -0
  31. package/Dockerfile.test +165 -0
  32. package/LICENSE +21 -0
  33. package/README.md +259 -0
  34. package/baremetal/commission-workflows.json +211 -0
  35. package/baremetal/packer-workflows.json +24 -0
  36. package/bin/build.js +261 -0
  37. package/bin/build.template.js +33 -0
  38. package/bin/cyberia.js +5627 -0
  39. package/bin/deploy.js +1547 -0
  40. package/bin/index.js +5627 -0
  41. package/bump.config.js +27 -0
  42. package/compose.env +144 -0
  43. package/conf.js +952 -0
  44. package/deployment.yaml +418 -0
  45. package/docker-compose.yml +434 -0
  46. package/examples/static-page/README.md +150 -0
  47. package/examples/static-page/ssr-components/CustomPage.js +554 -0
  48. package/examples/static-page/static-config-example.json +57 -0
  49. package/hardhat/.env.example +31 -0
  50. package/hardhat/contracts/ObjectLayerToken.sol +391 -0
  51. package/hardhat/deployments/.gitkeep +0 -0
  52. package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
  53. package/hardhat/hardhat.config.js +136 -0
  54. package/hardhat/ignition/modules/.gitkeep +0 -0
  55. package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
  56. package/hardhat/networks/besu-object-layer.network.json +138 -0
  57. package/hardhat/package-lock.json +2871 -0
  58. package/hardhat/package.json +43 -0
  59. package/hardhat/scripts/deployObjectLayerToken.js +98 -0
  60. package/hardhat/test/ObjectLayerToken.js +696 -0
  61. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  62. package/hardhat/types/ethers-contracts/common.ts +92 -0
  63. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  64. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  65. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  66. package/hardhat/types/ethers-contracts/index.ts +6 -0
  67. package/ipfs/configure-ipfs.sh +13 -0
  68. package/jsconfig.json +9 -0
  69. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +48 -0
  70. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +48 -0
  71. package/manifests/deployment/adminer/deployment.yaml +32 -0
  72. package/manifests/deployment/adminer/kustomization.yaml +7 -0
  73. package/manifests/deployment/adminer/service.yaml +13 -0
  74. package/manifests/deployment/dd-cyberia-development/deployment.yaml +418 -0
  75. package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
  76. package/manifests/deployment/dd-cyberia-development/proxy.yaml +189 -0
  77. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +164 -0
  78. package/manifests/deployment/dd-default-development/deployment.yaml +163 -0
  79. package/manifests/deployment/dd-default-development/proxy.yaml +46 -0
  80. package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
  81. package/manifests/deployment/fastapi/backend-service.yml +19 -0
  82. package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
  83. package/manifests/deployment/fastapi/frontend-service.yml +15 -0
  84. package/manifests/deployment/fastapi/initial_data.sh +8 -0
  85. package/manifests/deployment/kafka/deployment.yaml +67 -0
  86. package/manifests/deployment/mongo-express/deployment.yaml +62 -0
  87. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  88. package/manifests/deployment/playwright/deployment.yaml +52 -0
  89. package/manifests/deployment/spark/spark-pi-py.yaml +20 -0
  90. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +63 -0
  91. package/manifests/envoy-service-nodeport.yaml +22 -0
  92. package/manifests/grafana/deployment.yaml +64 -0
  93. package/manifests/grafana/kustomization.yaml +7 -0
  94. package/manifests/grafana/pvc.yaml +12 -0
  95. package/manifests/grafana/service.yaml +14 -0
  96. package/manifests/grafana/storage-class.yaml +9 -0
  97. package/manifests/ipfs/configmap.yaml +64 -0
  98. package/manifests/ipfs/headless-service.yaml +35 -0
  99. package/manifests/ipfs/kustomization.yaml +8 -0
  100. package/manifests/ipfs/statefulset.yaml +149 -0
  101. package/manifests/ipfs/storage-class.yaml +9 -0
  102. package/manifests/kind-config-dev.yaml +20 -0
  103. package/manifests/kind-config.yaml +12 -0
  104. package/manifests/kubeadm-calico-config.yaml +14 -0
  105. package/manifests/letsencrypt-prod.yaml +14 -0
  106. package/manifests/lxd/lxd-admin-profile.yaml +26 -0
  107. package/manifests/lxd/lxd-preseed.yaml +30 -0
  108. package/manifests/mariadb/kustomization.yaml +9 -0
  109. package/manifests/mariadb/pv.yaml +12 -0
  110. package/manifests/mariadb/pvc.yaml +10 -0
  111. package/manifests/mariadb/service.yaml +10 -0
  112. package/manifests/mariadb/statefulset.yaml +56 -0
  113. package/manifests/mariadb/storage-class.yaml +10 -0
  114. package/manifests/mongodb/headless-service.yaml +10 -0
  115. package/manifests/mongodb/kustomization.yaml +11 -0
  116. package/manifests/mongodb/pv-pvc.yaml +59 -0
  117. package/manifests/mongodb/statefulset.yaml +113 -0
  118. package/manifests/mongodb/storage-class.yaml +9 -0
  119. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  120. package/manifests/mongodb-4.4/kustomization.yaml +9 -0
  121. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  122. package/manifests/mongodb-4.4/pv-pvc.yaml +19 -0
  123. package/manifests/mongodb-4.4/service-deployment.yaml +61 -0
  124. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  125. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  126. package/manifests/mysql/kustomization.yaml +7 -0
  127. package/manifests/mysql/pv-pvc.yaml +27 -0
  128. package/manifests/mysql/statefulset.yaml +55 -0
  129. package/manifests/postgresql/configmap.yaml +9 -0
  130. package/manifests/postgresql/kustomization.yaml +10 -0
  131. package/manifests/postgresql/pv.yaml +15 -0
  132. package/manifests/postgresql/pvc.yaml +13 -0
  133. package/manifests/postgresql/service.yaml +10 -0
  134. package/manifests/postgresql/statefulset.yaml +37 -0
  135. package/manifests/prometheus/deployment.yaml +82 -0
  136. package/manifests/pv-pvc-dd.yaml +34 -0
  137. package/manifests/valkey/kustomization.yaml +7 -0
  138. package/manifests/valkey/service.yaml +10 -0
  139. package/manifests/valkey/statefulset.yaml +37 -0
  140. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  141. package/mongodb/entrypoint.sh +76 -0
  142. package/nginx.conf +128 -0
  143. package/nodemon.json +6 -0
  144. package/package.json +101 -0
  145. package/packer/images/Rocky9Amd64/Makefile +62 -0
  146. package/packer/images/Rocky9Amd64/QUICKSTART.md +113 -0
  147. package/packer/images/Rocky9Amd64/README.md +122 -0
  148. package/packer/images/Rocky9Amd64/http/rocky9.ks.pkrtpl.hcl +114 -0
  149. package/packer/images/Rocky9Amd64/rocky9.pkr.hcl +164 -0
  150. package/packer/images/Rocky9Arm64/Makefile +69 -0
  151. package/packer/images/Rocky9Arm64/README.md +122 -0
  152. package/packer/images/Rocky9Arm64/http/rocky9.ks.pkrtpl.hcl +114 -0
  153. package/packer/images/Rocky9Arm64/rocky9.pkr.hcl +171 -0
  154. package/packer/scripts/fuse-nbd +64 -0
  155. package/packer/scripts/fuse-tar-root +63 -0
  156. package/proxy.yaml +189 -0
  157. package/pv-pvc.yaml +164 -0
  158. package/scripts/device-scan.sh +65 -0
  159. package/scripts/disk-clean.sh +182 -0
  160. package/scripts/disk-devices.sh +13 -0
  161. package/scripts/gen-fqdns.sh +14 -0
  162. package/scripts/gpu-diag.sh +19 -0
  163. package/scripts/ip-info.sh +118 -0
  164. package/scripts/ipxe-setup.sh +200 -0
  165. package/scripts/k3s-node-setup.sh +124 -0
  166. package/scripts/kubeadm-node-setup.sh +317 -0
  167. package/scripts/link-local-underpost-cli.sh +6 -0
  168. package/scripts/lxd-vm-setup.sh +208 -0
  169. package/scripts/maas-nat-firewalld.sh +145 -0
  170. package/scripts/maas-setup.sh +135 -0
  171. package/scripts/maas-upload-boot-resource.sh +183 -0
  172. package/scripts/nat-iptables.sh +111 -0
  173. package/scripts/nvim.sh +91 -0
  174. package/scripts/packer-init-vars-file.sh +40 -0
  175. package/scripts/packer-setup.sh +289 -0
  176. package/scripts/ports-ls.sh +33 -0
  177. package/scripts/quick-tftp.sh +19 -0
  178. package/scripts/rhel-grpc-setup.sh +56 -0
  179. package/scripts/rocky-kickstart.sh +986 -0
  180. package/scripts/rocky-pwa.sh +200 -0
  181. package/scripts/rocky-setup.sh +106 -0
  182. package/scripts/rpmfusion-ffmpeg-setup.sh +32 -0
  183. package/scripts/ssl.sh +170 -0
  184. package/scripts/test-monitor.sh +248 -0
  185. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +30 -0
  186. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +155 -0
  187. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +39 -0
  188. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +382 -0
  189. package/src/api/core/core.controller.js +8 -0
  190. package/src/api/core/core.model.js +11 -0
  191. package/src/api/core/core.router.js +23 -0
  192. package/src/api/core/core.service.js +30 -0
  193. package/src/api/crypto/crypto.controller.js +10 -0
  194. package/src/api/crypto/crypto.model.js +23 -0
  195. package/src/api/crypto/crypto.router.js +23 -0
  196. package/src/api/crypto/crypto.service.js +64 -0
  197. package/src/api/cyberia-action/cyberia-action.controller.js +8 -0
  198. package/src/api/cyberia-action/cyberia-action.model.js +79 -0
  199. package/src/api/cyberia-action/cyberia-action.router.js +21 -0
  200. package/src/api/cyberia-action/cyberia-action.service.js +58 -0
  201. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +27 -0
  202. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +100 -0
  203. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +70 -0
  204. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  205. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +8 -0
  206. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  207. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +20 -0
  208. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +57 -0
  209. package/src/api/cyberia-entity/cyberia-entity.controller.js +6 -0
  210. package/src/api/cyberia-entity/cyberia-entity.model.js +25 -0
  211. package/src/api/cyberia-entity/cyberia-entity.router.js +17 -0
  212. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  213. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +6 -0
  214. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
  215. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -0
  216. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
  217. package/src/api/cyberia-instance/cyberia-fallback-world.js +337 -0
  218. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +57 -0
  219. package/src/api/cyberia-instance/cyberia-instance-map.service.js +583 -0
  220. package/src/api/cyberia-instance/cyberia-instance.controller.js +42 -0
  221. package/src/api/cyberia-instance/cyberia-instance.model.js +117 -0
  222. package/src/api/cyberia-instance/cyberia-instance.router.js +75 -0
  223. package/src/api/cyberia-instance/cyberia-instance.service.js +190 -0
  224. package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
  225. package/src/api/cyberia-instance/cyberia-world-generator.js +618 -0
  226. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +6 -0
  227. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +200 -0
  228. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +17 -0
  229. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
  230. package/src/api/cyberia-map/cyberia-map.controller.js +6 -0
  231. package/src/api/cyberia-map/cyberia-map.model.js +33 -0
  232. package/src/api/cyberia-map/cyberia-map.router.js +19 -0
  233. package/src/api/cyberia-map/cyberia-map.service.js +76 -0
  234. package/src/api/cyberia-quest/cyberia-quest.controller.js +9 -0
  235. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  236. package/src/api/cyberia-quest/cyberia-quest.router.js +26 -0
  237. package/src/api/cyberia-quest/cyberia-quest.service.js +97 -0
  238. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +6 -0
  239. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  240. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +21 -0
  241. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  242. package/src/api/cyberia-saga/cyberia-saga.controller.js +6 -0
  243. package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
  244. package/src/api/cyberia-saga/cyberia-saga.router.js +17 -0
  245. package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
  246. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +1076 -0
  247. package/src/api/cyberia-skill/cyberia-skill.controller.js +6 -0
  248. package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
  249. package/src/api/cyberia-skill/cyberia-skill.router.js +17 -0
  250. package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
  251. package/src/api/default/default.controller.js +6 -0
  252. package/src/api/default/default.model.js +20 -0
  253. package/src/api/default/default.router.js +21 -0
  254. package/src/api/default/default.service.js +42 -0
  255. package/src/api/document/document.controller.js +9 -0
  256. package/src/api/document/document.model.js +95 -0
  257. package/src/api/document/document.router.js +32 -0
  258. package/src/api/document/document.service.js +633 -0
  259. package/src/api/file/file.controller.js +15 -0
  260. package/src/api/file/file.model.js +127 -0
  261. package/src/api/file/file.ref.json +39 -0
  262. package/src/api/file/file.router.js +36 -0
  263. package/src/api/file/file.service.js +499 -0
  264. package/src/api/instance/instance.controller.js +8 -0
  265. package/src/api/instance/instance.model.js +34 -0
  266. package/src/api/instance/instance.router.js +27 -0
  267. package/src/api/instance/instance.service.js +75 -0
  268. package/src/api/ipfs/ipfs.controller.js +8 -0
  269. package/src/api/ipfs/ipfs.model.js +77 -0
  270. package/src/api/ipfs/ipfs.router.js +26 -0
  271. package/src/api/ipfs/ipfs.service.js +145 -0
  272. package/src/api/object-layer/object-layer.controller.js +18 -0
  273. package/src/api/object-layer/object-layer.model.js +200 -0
  274. package/src/api/object-layer/object-layer.router.js +729 -0
  275. package/src/api/object-layer/object-layer.service.js +894 -0
  276. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +6 -0
  277. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +93 -0
  278. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +17 -0
  279. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +46 -0
  280. package/src/api/test/test.controller.js +14 -0
  281. package/src/api/test/test.model.js +14 -0
  282. package/src/api/test/test.router.js +23 -0
  283. package/src/api/test/test.service.js +35 -0
  284. package/src/api/types.js +24 -0
  285. package/src/api/user/guest.service.js +100 -0
  286. package/src/api/user/postman_collection.json +216 -0
  287. package/src/api/user/user.build.js +16 -0
  288. package/src/api/user/user.controller.js +35 -0
  289. package/src/api/user/user.model.js +142 -0
  290. package/src/api/user/user.router.js +367 -0
  291. package/src/api/user/user.service.js +582 -0
  292. package/src/api.js +23 -0
  293. package/src/cli/baremetal.js +3947 -0
  294. package/src/cli/cloud-init.js +673 -0
  295. package/src/cli/cluster.js +1395 -0
  296. package/src/cli/db.js +1533 -0
  297. package/src/cli/deploy.js +1542 -0
  298. package/src/cli/docker-compose.js +802 -0
  299. package/src/cli/env.js +177 -0
  300. package/src/cli/fs.js +380 -0
  301. package/src/cli/image.js +389 -0
  302. package/src/cli/index.js +1059 -0
  303. package/src/cli/ipfs.js +182 -0
  304. package/src/cli/kickstart.js +271 -0
  305. package/src/cli/kubectl.js +214 -0
  306. package/src/cli/lxd.js +1232 -0
  307. package/src/cli/monitor.js +659 -0
  308. package/src/cli/release.js +595 -0
  309. package/src/cli/repository.js +1969 -0
  310. package/src/cli/run.js +3326 -0
  311. package/src/cli/secrets.js +151 -0
  312. package/src/cli/ssh.js +975 -0
  313. package/src/cli/static.js +653 -0
  314. package/src/cli/system.js +332 -0
  315. package/src/cli/test.js +176 -0
  316. package/src/client/Cryptokoyn.index.js +30 -0
  317. package/src/client/CyberiaPortal.index.js +31 -0
  318. package/src/client/Default.index.js +77 -0
  319. package/src/client/Itemledger.index.js +35 -0
  320. package/src/client/Underpost.index.js +31 -0
  321. package/src/client/components/core/404.js +20 -0
  322. package/src/client/components/core/500.js +20 -0
  323. package/src/client/components/core/Account.js +630 -0
  324. package/src/client/components/core/AgGrid.js +238 -0
  325. package/src/client/components/core/Alert.js +76 -0
  326. package/src/client/components/core/AppStore.js +69 -0
  327. package/src/client/components/core/Auth.js +353 -0
  328. package/src/client/components/core/Badge.js +26 -0
  329. package/src/client/components/core/Blockchain.js +41 -0
  330. package/src/client/components/core/Blog.js +9 -0
  331. package/src/client/components/core/BtnIcon.js +109 -0
  332. package/src/client/components/core/CalendarCore.js +437 -0
  333. package/src/client/components/core/Chat.js +62 -0
  334. package/src/client/components/core/ClientEvents.js +163 -0
  335. package/src/client/components/core/ColorPaletteElement.js +309 -0
  336. package/src/client/components/core/CommonJs.js +1014 -0
  337. package/src/client/components/core/Content.js +349 -0
  338. package/src/client/components/core/Css.js +1134 -0
  339. package/src/client/components/core/CssCore.js +881 -0
  340. package/src/client/components/core/D3Chart.js +44 -0
  341. package/src/client/components/core/Docs.js +478 -0
  342. package/src/client/components/core/DropDown.js +321 -0
  343. package/src/client/components/core/EventBus.js +96 -0
  344. package/src/client/components/core/EventsUI.js +130 -0
  345. package/src/client/components/core/FileExplorer.js +1406 -0
  346. package/src/client/components/core/FullScreen.js +201 -0
  347. package/src/client/components/core/Input.js +537 -0
  348. package/src/client/components/core/Keyboard.js +80 -0
  349. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  350. package/src/client/components/core/LoadingAnimation.js +152 -0
  351. package/src/client/components/core/LogIn.js +212 -0
  352. package/src/client/components/core/LogOut.js +72 -0
  353. package/src/client/components/core/Logger.js +22 -0
  354. package/src/client/components/core/Modal.js +2956 -0
  355. package/src/client/components/core/NotificationManager.js +80 -0
  356. package/src/client/components/core/Pagination.js +252 -0
  357. package/src/client/components/core/Panel.js +1308 -0
  358. package/src/client/components/core/PanelForm.js +915 -0
  359. package/src/client/components/core/Polyhedron.js +947 -0
  360. package/src/client/components/core/PublicProfile.js +895 -0
  361. package/src/client/components/core/Recover.js +211 -0
  362. package/src/client/components/core/Responsive.js +146 -0
  363. package/src/client/components/core/RichText.js +33 -0
  364. package/src/client/components/core/Router.js +523 -0
  365. package/src/client/components/core/Scroll.js +76 -0
  366. package/src/client/components/core/SearchBox.js +1007 -0
  367. package/src/client/components/core/SignUp.js +153 -0
  368. package/src/client/components/core/SocketIo.js +163 -0
  369. package/src/client/components/core/SocketIoHandler.js +75 -0
  370. package/src/client/components/core/Stream.js +161 -0
  371. package/src/client/components/core/ToggleSwitch.js +89 -0
  372. package/src/client/components/core/ToolTip.js +78 -0
  373. package/src/client/components/core/Translate.js +694 -0
  374. package/src/client/components/core/Validator.js +140 -0
  375. package/src/client/components/core/VanillaJs.js +485 -0
  376. package/src/client/components/core/Wallet.js +95 -0
  377. package/src/client/components/core/WebComponent.js +44 -0
  378. package/src/client/components/core/Webhook.js +58 -0
  379. package/src/client/components/core/Worker.js +313 -0
  380. package/src/client/components/core/windowGetDimensions.js +269 -0
  381. package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +352 -0
  382. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  383. package/src/client/components/cryptokoyn/CssCryptokoyn.js +212 -0
  384. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +16 -0
  385. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +12 -0
  386. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  387. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +16 -0
  388. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +11 -0
  389. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +6 -0
  390. package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
  391. package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
  392. package/src/client/components/cyberia/InstanceEngineCyberia.js +1088 -0
  393. package/src/client/components/cyberia/InstanceSelectionView.js +900 -0
  394. package/src/client/components/cyberia/MapEngineCyberia.js +1976 -0
  395. package/src/client/components/cyberia/ObjectLayerEngine.js +1540 -0
  396. package/src/client/components/cyberia/ObjectLayerEngineModal.js +2420 -0
  397. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +1522 -0
  398. package/src/client/components/cyberia/SharedDefaultsCyberia.js +528 -0
  399. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +772 -0
  400. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  401. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +254 -0
  402. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +21 -0
  403. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +16 -0
  404. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +518 -0
  405. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +72 -0
  406. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +16 -0
  407. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +13 -0
  408. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +6 -0
  409. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +48 -0
  410. package/src/client/components/default/AppShellDefault.js +765 -0
  411. package/src/client/components/default/AppStoreDefault.js +5 -0
  412. package/src/client/components/default/CommonDefault.js +29 -0
  413. package/src/client/components/default/CssDefault.js +27 -0
  414. package/src/client/components/default/LogInDefault.js +16 -0
  415. package/src/client/components/default/LogOutDefault.js +12 -0
  416. package/src/client/components/default/RouterDefault.js +47 -0
  417. package/src/client/components/default/SettingsDefault.js +16 -0
  418. package/src/client/components/default/SignUpDefault.js +11 -0
  419. package/src/client/components/default/SocketIoDefault.js +6 -0
  420. package/src/client/components/default/TranslateDefault.js +7 -0
  421. package/src/client/components/itemledger/AppShellItemledger.js +353 -0
  422. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  423. package/src/client/components/itemledger/CssItemledger.js +212 -0
  424. package/src/client/components/itemledger/LogInItemledger.js +17 -0
  425. package/src/client/components/itemledger/LogOutItemledger.js +12 -0
  426. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  427. package/src/client/components/itemledger/SettingsItemledger.js +16 -0
  428. package/src/client/components/itemledger/SignUpItemledger.js +11 -0
  429. package/src/client/components/itemledger/SocketIoItemledger.js +6 -0
  430. package/src/client/components/itemledger/TranslateItemledger.js +7 -0
  431. package/src/client/components/underpost/AppShellUnderpost.js +691 -0
  432. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  433. package/src/client/components/underpost/CssUnderpost.js +281 -0
  434. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
  435. package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
  436. package/src/client/components/underpost/LabGalleryUnderpost.js +79 -0
  437. package/src/client/components/underpost/LogInUnderpost.js +25 -0
  438. package/src/client/components/underpost/LogOutUnderpost.js +17 -0
  439. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  440. package/src/client/components/underpost/SettingsUnderpost.js +16 -0
  441. package/src/client/components/underpost/SignUpUnderpost.js +11 -0
  442. package/src/client/components/underpost/SocketIoUnderpost.js +6 -0
  443. package/src/client/components/underpost/TranslateUnderpost.js +10 -0
  444. package/src/client/public/cryptokoyn/assets/banner/koyn-social.png +0 -0
  445. package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
  446. package/src/client/public/cryptokoyn/assets/logo/cryptokoyn.png +0 -0
  447. package/src/client/public/cryptokoyn/assets/splash/android-chrome-144x144.png +0 -0
  448. package/src/client/public/cryptokoyn/assets/splash/android-chrome-192x192.png +0 -0
  449. package/src/client/public/cryptokoyn/assets/splash/android-chrome-256x256.png +0 -0
  450. package/src/client/public/cryptokoyn/assets/splash/android-chrome-36x36.png +0 -0
  451. package/src/client/public/cryptokoyn/assets/splash/android-chrome-48x48.png +0 -0
  452. package/src/client/public/cryptokoyn/assets/splash/android-chrome-72x72.png +0 -0
  453. package/src/client/public/cryptokoyn/assets/splash/android-chrome-96x96.png +0 -0
  454. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114-precomposed.png +0 -0
  455. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114.png +0 -0
  456. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120-precomposed.png +0 -0
  457. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120.png +0 -0
  458. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144-precomposed.png +0 -0
  459. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144.png +0 -0
  460. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152-precomposed.png +0 -0
  461. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152.png +0 -0
  462. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180-precomposed.png +0 -0
  463. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180.png +0 -0
  464. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57-precomposed.png +0 -0
  465. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57.png +0 -0
  466. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60-precomposed.png +0 -0
  467. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60.png +0 -0
  468. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72-precomposed.png +0 -0
  469. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72.png +0 -0
  470. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76-precomposed.png +0 -0
  471. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76.png +0 -0
  472. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-precomposed.png +0 -0
  473. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon.png +0 -0
  474. package/src/client/public/cryptokoyn/assets/splash/favicon-16x16.png +0 -0
  475. package/src/client/public/cryptokoyn/assets/splash/favicon-32x32.png +0 -0
  476. package/src/client/public/cryptokoyn/assets/splash/mstile-144x144.png +0 -0
  477. package/src/client/public/cryptokoyn/assets/splash/mstile-150x150.png +0 -0
  478. package/src/client/public/cryptokoyn/assets/splash/mstile-310x150.png +0 -0
  479. package/src/client/public/cryptokoyn/assets/splash/mstile-310x310.png +0 -0
  480. package/src/client/public/cryptokoyn/assets/splash/mstile-70x70.png +0 -0
  481. package/src/client/public/cryptokoyn/assets/splash/safari-pinned-tab.svg +42 -0
  482. package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
  483. package/src/client/public/cryptokoyn/favicon.ico +0 -0
  484. package/src/client/public/cryptokoyn/microdata.json +85 -0
  485. package/src/client/public/cryptokoyn/site.webmanifest +57 -0
  486. package/src/client/public/cryptokoyn/sitemap +148 -0
  487. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +307 -0
  488. package/src/client/public/cyberia-docs/ARCHITECTURE.md +309 -0
  489. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +204 -0
  490. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +341 -0
  491. package/src/client/public/cyberia-docs/CYBERIA-LORE.md +84 -0
  492. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
  493. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +294 -0
  494. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  495. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +242 -0
  496. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  497. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +309 -0
  498. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +228 -0
  499. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  500. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  501. package/src/client/public/cyberia-docs/WHITE-PAPER.md +740 -0
  502. package/src/client/public/default/android-chrome-144x144.png +0 -0
  503. package/src/client/public/default/android-chrome-192x192.png +0 -0
  504. package/src/client/public/default/android-chrome-256x256.png +0 -0
  505. package/src/client/public/default/android-chrome-36x36.png +0 -0
  506. package/src/client/public/default/android-chrome-384x384.png +0 -0
  507. package/src/client/public/default/android-chrome-48x48.png +0 -0
  508. package/src/client/public/default/android-chrome-512x512.png +0 -0
  509. package/src/client/public/default/android-chrome-72x72.png +0 -0
  510. package/src/client/public/default/android-chrome-96x96.png +0 -0
  511. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  512. package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
  513. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  514. package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
  515. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  516. package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
  517. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  518. package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
  519. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  520. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  521. package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
  522. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  523. package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
  524. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  525. package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
  526. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  527. package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
  528. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  529. package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
  530. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  531. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  532. package/src/client/public/default/apple-touch-icon.png +0 -0
  533. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  534. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  535. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  536. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  537. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  538. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  539. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  540. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  541. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  542. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  543. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  544. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  545. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  546. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  547. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  548. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  549. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  550. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  551. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  552. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  553. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  554. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  555. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  556. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  557. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  558. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  559. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  560. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  561. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  562. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  563. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  564. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  565. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  566. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  567. package/src/client/public/default/assets/background/dark.jpg +0 -0
  568. package/src/client/public/default/assets/background/dark.svg +557 -0
  569. package/src/client/public/default/assets/background/white.jpg +0 -0
  570. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  571. package/src/client/public/default/assets/background/white0.jpg +0 -0
  572. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  573. package/src/client/public/default/assets/logo/underpost.gif +0 -0
  574. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  575. package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
  576. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  577. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  578. package/src/client/public/default/browserconfig.xml +12 -0
  579. package/src/client/public/default/favicon-16x16.png +0 -0
  580. package/src/client/public/default/favicon-32x32.png +0 -0
  581. package/src/client/public/default/favicon-48x48.png +0 -0
  582. package/src/client/public/default/favicon.ico +0 -0
  583. package/src/client/public/default/manifest.webmanifest +69 -0
  584. package/src/client/public/default/mstile-144x144.png +0 -0
  585. package/src/client/public/default/mstile-150x150.png +0 -0
  586. package/src/client/public/default/mstile-310x150.png +0 -0
  587. package/src/client/public/default/mstile-310x310.png +0 -0
  588. package/src/client/public/default/mstile-70x70.png +0 -0
  589. package/src/client/public/default/safari-pinned-tab.svg +24 -0
  590. package/src/client/public/default/site.webmanifest +69 -0
  591. package/src/client/public/default/sitemap +148 -0
  592. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  593. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  594. package/src/client/public/doc/favicon.ico +0 -0
  595. package/src/client/public/doc/sitemap +148 -0
  596. package/src/client/public/itemledger/android-chrome-144x144.png +0 -0
  597. package/src/client/public/itemledger/android-chrome-192x192.png +0 -0
  598. package/src/client/public/itemledger/android-chrome-256x256.png +0 -0
  599. package/src/client/public/itemledger/android-chrome-36x36.png +0 -0
  600. package/src/client/public/itemledger/android-chrome-384x384.png +0 -0
  601. package/src/client/public/itemledger/android-chrome-48x48.png +0 -0
  602. package/src/client/public/itemledger/android-chrome-512x512.png +0 -0
  603. package/src/client/public/itemledger/android-chrome-72x72.png +0 -0
  604. package/src/client/public/itemledger/android-chrome-96x96.png +0 -0
  605. package/src/client/public/itemledger/apple-touch-icon-1024x1024.png +0 -0
  606. package/src/client/public/itemledger/apple-touch-icon-114x114.png +0 -0
  607. package/src/client/public/itemledger/apple-touch-icon-120x120.png +0 -0
  608. package/src/client/public/itemledger/apple-touch-icon-144x144.png +0 -0
  609. package/src/client/public/itemledger/apple-touch-icon-152x152.png +0 -0
  610. package/src/client/public/itemledger/apple-touch-icon-167x167.png +0 -0
  611. package/src/client/public/itemledger/apple-touch-icon-180x180.png +0 -0
  612. package/src/client/public/itemledger/apple-touch-icon-57x57.png +0 -0
  613. package/src/client/public/itemledger/apple-touch-icon-60x60.png +0 -0
  614. package/src/client/public/itemledger/apple-touch-icon-72x72.png +0 -0
  615. package/src/client/public/itemledger/apple-touch-icon-76x76.png +0 -0
  616. package/src/client/public/itemledger/apple-touch-icon-precomposed.png +0 -0
  617. package/src/client/public/itemledger/apple-touch-icon.png +0 -0
  618. package/src/client/public/itemledger/apple-touch-startup-image-1125x2436.png +0 -0
  619. package/src/client/public/itemledger/apple-touch-startup-image-1136x640.png +0 -0
  620. package/src/client/public/itemledger/apple-touch-startup-image-1170x2532.png +0 -0
  621. package/src/client/public/itemledger/apple-touch-startup-image-1179x2556.png +0 -0
  622. package/src/client/public/itemledger/apple-touch-startup-image-1242x2208.png +0 -0
  623. package/src/client/public/itemledger/apple-touch-startup-image-1242x2688.png +0 -0
  624. package/src/client/public/itemledger/apple-touch-startup-image-1284x2778.png +0 -0
  625. package/src/client/public/itemledger/apple-touch-startup-image-1290x2796.png +0 -0
  626. package/src/client/public/itemledger/apple-touch-startup-image-1334x750.png +0 -0
  627. package/src/client/public/itemledger/apple-touch-startup-image-1488x2266.png +0 -0
  628. package/src/client/public/itemledger/apple-touch-startup-image-1536x2048.png +0 -0
  629. package/src/client/public/itemledger/apple-touch-startup-image-1620x2160.png +0 -0
  630. package/src/client/public/itemledger/apple-touch-startup-image-1640x2160.png +0 -0
  631. package/src/client/public/itemledger/apple-touch-startup-image-1668x2224.png +0 -0
  632. package/src/client/public/itemledger/apple-touch-startup-image-1668x2388.png +0 -0
  633. package/src/client/public/itemledger/apple-touch-startup-image-1792x828.png +0 -0
  634. package/src/client/public/itemledger/apple-touch-startup-image-2048x1536.png +0 -0
  635. package/src/client/public/itemledger/apple-touch-startup-image-2048x2732.png +0 -0
  636. package/src/client/public/itemledger/apple-touch-startup-image-2160x1620.png +0 -0
  637. package/src/client/public/itemledger/apple-touch-startup-image-2160x1640.png +0 -0
  638. package/src/client/public/itemledger/apple-touch-startup-image-2208x1242.png +0 -0
  639. package/src/client/public/itemledger/apple-touch-startup-image-2224x1668.png +0 -0
  640. package/src/client/public/itemledger/apple-touch-startup-image-2266x1488.png +0 -0
  641. package/src/client/public/itemledger/apple-touch-startup-image-2388x1668.png +0 -0
  642. package/src/client/public/itemledger/apple-touch-startup-image-2436x1125.png +0 -0
  643. package/src/client/public/itemledger/apple-touch-startup-image-2532x1170.png +0 -0
  644. package/src/client/public/itemledger/apple-touch-startup-image-2556x1179.png +0 -0
  645. package/src/client/public/itemledger/apple-touch-startup-image-2688x1242.png +0 -0
  646. package/src/client/public/itemledger/apple-touch-startup-image-2732x2048.png +0 -0
  647. package/src/client/public/itemledger/apple-touch-startup-image-2778x1284.png +0 -0
  648. package/src/client/public/itemledger/apple-touch-startup-image-2796x1290.png +0 -0
  649. package/src/client/public/itemledger/apple-touch-startup-image-640x1136.png +0 -0
  650. package/src/client/public/itemledger/apple-touch-startup-image-750x1334.png +0 -0
  651. package/src/client/public/itemledger/apple-touch-startup-image-828x1792.png +0 -0
  652. package/src/client/public/itemledger/assets/logo/base-icon.png +0 -0
  653. package/src/client/public/itemledger/browserconfig.xml +12 -0
  654. package/src/client/public/itemledger/favicon-16x16.png +0 -0
  655. package/src/client/public/itemledger/favicon-32x32.png +0 -0
  656. package/src/client/public/itemledger/favicon-48x48.png +0 -0
  657. package/src/client/public/itemledger/favicon.ico +0 -0
  658. package/src/client/public/itemledger/manifest.webmanifest +69 -0
  659. package/src/client/public/itemledger/microdata.json +71 -0
  660. package/src/client/public/itemledger/mstile-144x144.png +0 -0
  661. package/src/client/public/itemledger/mstile-150x150.png +0 -0
  662. package/src/client/public/itemledger/mstile-310x150.png +0 -0
  663. package/src/client/public/itemledger/mstile-310x310.png +0 -0
  664. package/src/client/public/itemledger/mstile-70x70.png +0 -0
  665. package/src/client/public/itemledger/sitemap +148 -0
  666. package/src/client/public/itemledger/yandex-browser-50x50.png +0 -0
  667. package/src/client/public/itemledger/yandex-browser-manifest.json +9 -0
  668. package/src/client/public/test/favicon.ico +0 -0
  669. package/src/client/public/test/sitemap +148 -0
  670. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +137 -0
  671. package/src/client/services/core/core.service.js +309 -0
  672. package/src/client/services/crypto/crypto.service.js +68 -0
  673. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  674. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  675. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
  676. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  677. package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
  678. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
  679. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  680. package/src/client/services/cyberia-instance/cyberia-instance.service.js +137 -0
  681. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
  682. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  683. package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
  684. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  685. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  686. package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
  687. package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
  688. package/src/client/services/default/default.management.js +1015 -0
  689. package/src/client/services/default/default.service.js +99 -0
  690. package/src/client/services/document/document.service.js +134 -0
  691. package/src/client/services/file/file.service.js +94 -0
  692. package/src/client/services/instance/instance.management.js +78 -0
  693. package/src/client/services/instance/instance.service.js +107 -0
  694. package/src/client/services/ipfs/ipfs.service.js +118 -0
  695. package/src/client/services/object-layer/object-layer.management.js +414 -0
  696. package/src/client/services/object-layer/object-layer.service.js +208 -0
  697. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +99 -0
  698. package/src/client/services/test/test.service.js +68 -0
  699. package/src/client/services/user/guest.service.js +86 -0
  700. package/src/client/services/user/user.management.js +51 -0
  701. package/src/client/services/user/user.service.js +106 -0
  702. package/src/client/ssr/RootDocument.js +237 -0
  703. package/src/client/ssr/body/404.js +77 -0
  704. package/src/client/ssr/body/500.js +76 -0
  705. package/src/client/ssr/body/CacheControl.js +117 -0
  706. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +97 -0
  707. package/src/client/ssr/body/DefaultSplashScreen.js +97 -0
  708. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  709. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +90 -0
  710. package/src/client/ssr/head/CryptokoynScripts.js +4 -0
  711. package/src/client/ssr/head/Css.js +241 -0
  712. package/src/client/ssr/head/CyberiaPortalScripts.js +6 -0
  713. package/src/client/ssr/head/DefaultScripts.js +6 -0
  714. package/src/client/ssr/head/ItemledgerScripts.js +4 -0
  715. package/src/client/ssr/head/Microdata.js +11 -0
  716. package/src/client/ssr/head/Production.js +1 -0
  717. package/src/client/ssr/head/Pwa.js +146 -0
  718. package/src/client/ssr/head/PwaItemledger.js +197 -0
  719. package/src/client/ssr/head/Seo.js +15 -0
  720. package/src/client/ssr/head/UnderpostScripts.js +6 -0
  721. package/src/client/ssr/mailer/DefaultRecoverEmail.js +20 -0
  722. package/src/client/ssr/mailer/DefaultVerifyEmail.js +16 -0
  723. package/src/client/ssr/views/Cyberia404.js +328 -0
  724. package/src/client/ssr/views/CyberiaServerMetrics.js +1070 -0
  725. package/src/client/ssr/views/Maintenance.js +64 -0
  726. package/src/client/ssr/views/NoNetworkConnection.js +68 -0
  727. package/src/client/ssr/views/Test.js +199 -0
  728. package/src/client/sw/core.sw.js +274 -0
  729. package/src/client-builder/client-build-docs.js +493 -0
  730. package/src/client-builder/client-build-live.js +100 -0
  731. package/src/client-builder/client-build.js +1092 -0
  732. package/src/client-builder/client-dev-server.js +88 -0
  733. package/src/client-builder/client-formatted.js +170 -0
  734. package/src/client-builder/client-icons.js +108 -0
  735. package/src/client-builder/ssr.js +124 -0
  736. package/src/client.build.js +17 -0
  737. package/src/client.dev.js +21 -0
  738. package/src/db/DataBaseProvider.js +213 -0
  739. package/src/db/mariadb/MariaDB.js +72 -0
  740. package/src/db/mongo/MongoBootstrap.js +657 -0
  741. package/src/db/mongo/MongooseDB.js +199 -0
  742. package/src/grpc/cyberia/grpc-server.js +162 -0
  743. package/src/index.js +357 -0
  744. package/src/mailer/EmailRender.js +116 -0
  745. package/src/mailer/MailerProvider.js +213 -0
  746. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +413 -0
  747. package/src/projects/cyberia/besu-genesis-generator.js +1630 -0
  748. package/src/projects/cyberia/catalog-cyberia.js +90 -0
  749. package/src/projects/cyberia/gemini-client.js +175 -0
  750. package/src/projects/cyberia/generate-saga.js +2137 -0
  751. package/src/projects/cyberia/hot-reload-trigger.js +163 -0
  752. package/src/projects/cyberia/instance-data.js +719 -0
  753. package/src/projects/cyberia/ipfs-client.js +599 -0
  754. package/src/projects/cyberia/map-preview-generator.js +304 -0
  755. package/src/projects/cyberia/object-layer.js +978 -0
  756. package/src/projects/cyberia/semantic-layer-generator-floor.js +319 -0
  757. package/src/projects/cyberia/semantic-layer-generator-resource.js +259 -0
  758. package/src/projects/cyberia/semantic-layer-generator-skin.js +1164 -0
  759. package/src/projects/cyberia/semantic-layer-generator.js +753 -0
  760. package/src/projects/cyberia/shape-generator.js +1060 -0
  761. package/src/projects/underpost/catalog-underpost.js +60 -0
  762. package/src/proxy.js +19 -0
  763. package/src/runtime/cyberia-client/Dockerfile +49 -0
  764. package/src/runtime/cyberia-client/Dockerfile.dev +75 -0
  765. package/src/runtime/cyberia-server/Dockerfile +43 -0
  766. package/src/runtime/cyberia-server/Dockerfile.dev +56 -0
  767. package/src/runtime/engine-cyberia/Dockerfile +161 -0
  768. package/src/runtime/engine-cyberia/Dockerfile.dev +161 -0
  769. package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
  770. package/src/runtime/engine-cyberia/compose.env +144 -0
  771. package/src/runtime/engine-cyberia/docker-compose.yml +434 -0
  772. package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
  773. package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
  774. package/src/runtime/engine-cyberia/nginx.conf +128 -0
  775. package/src/runtime/express/Dockerfile +45 -0
  776. package/src/runtime/express/Express.js +285 -0
  777. package/src/runtime/lampp/Dockerfile +62 -0
  778. package/src/runtime/lampp/Lampp.js +359 -0
  779. package/src/runtime/nginx/Nginx.js +250 -0
  780. package/src/runtime/wp/Dockerfile +62 -0
  781. package/src/runtime/wp/Wp.js +642 -0
  782. package/src/server/auth.js +713 -0
  783. package/src/server/backup.js +102 -0
  784. package/src/server/catalog.js +72 -0
  785. package/src/server/conf.js +2316 -0
  786. package/src/server/cron.js +476 -0
  787. package/src/server/crypto.js +210 -0
  788. package/src/server/data-query.js +461 -0
  789. package/src/server/dns.js +553 -0
  790. package/src/server/downloader.js +73 -0
  791. package/src/server/logger.js +229 -0
  792. package/src/server/middlewares.js +152 -0
  793. package/src/server/peer.js +75 -0
  794. package/src/server/process.js +299 -0
  795. package/src/server/proxy.js +139 -0
  796. package/src/server/runtime-status.js +252 -0
  797. package/src/server/runtime.js +183 -0
  798. package/src/server/start.js +272 -0
  799. package/src/server/tls.js +254 -0
  800. package/src/server/valkey.js +201 -0
  801. package/src/server.js +25 -0
  802. package/src/ws/IoInterface.js +129 -0
  803. package/src/ws/IoServer.js +68 -0
  804. package/src/ws/core/channels/core.ws.chat.js +68 -0
  805. package/src/ws/core/channels/core.ws.mailer.js +116 -0
  806. package/src/ws/core/channels/core.ws.stream.js +90 -0
  807. package/src/ws/core/core.ws.connection.js +41 -0
  808. package/src/ws/core/core.ws.emit.js +37 -0
  809. package/src/ws/core/core.ws.server.js +44 -0
  810. package/src/ws/default/channels/default.ws.main.js +57 -0
  811. package/src/ws/default/default.ws.connection.js +35 -0
  812. package/src/ws/default/default.ws.emit.js +14 -0
  813. package/src/ws/default/default.ws.server.js +39 -0
  814. package/test/api.test.js +53 -0
  815. package/test/crypto.test.js +117 -0
  816. package/test/cyberia-instance-conf-defaults.test.js +140 -0
  817. package/test/deploy-monitor.test.js +267 -0
  818. package/test/shape-generator.test.js +463 -0
  819. package/tsconfig.docs.json +15 -0
  820. package/typedoc.dd-cyberia.json +31 -0
  821. package/typedoc.json +31 -0
@@ -0,0 +1,986 @@
1
+ #!/bin/bash
2
+ # Rocky Linux 9 - Anaconda %pre Ephemeral Commissioning + Disk Install Script
3
+ #
4
+ # This script runs inside the ephemeral Anaconda live environment (booted via
5
+ # iPXE/HTTP with inst.sshd). It drives the full unattended lifecycle:
6
+ #
7
+ # 1. ephemeral boot up (Anaconda live, this %pre script starts)
8
+ # 2. ssh ready (key-only sshd up and verified listening)
9
+ # 3. metadata posted (async POST stage=ssh-ready to bootstrap server)
10
+ # 4. remote install executed (controller SSHes in and runs the installer,
11
+ # or AUTO_INSTALL fallback self-triggers it)
12
+ # 5. disk installation (POST stage=installing; Rocky written to disk)
13
+ # 6. install completed (POST stage=completed)
14
+ # 7. reboot (boot order points at the freshly written disk)
15
+ # 8. boot into deployed OS
16
+ #
17
+ # Variables injected by the kickstart %pre header (kickstart.js):
18
+ # ROOT_PASS, AUTHORIZED_KEYS, ADMIN_USER,
19
+ # BOOTSTRAP_URL, WORKFLOW_ID, SYSTEM_ID, TARGET_HOSTNAME,
20
+ # SSH_PORT, INSTALL_DISK_HINT, AUTO_INSTALL
21
+
22
+ set +e
23
+
24
+ SSH_PORT="${SSH_PORT:-22}"
25
+ AUTO_INSTALL="${AUTO_INSTALL:-1}"
26
+ # Fallback: if no remote install trigger arrives within this window, the
27
+ # ephemeral runtime self-installs so a single missed handshake never bricks the
28
+ # flow. The controller normally triggers far sooner over SSH.
29
+ AUTO_INSTALL_FALLBACK_SECONDS="${AUTO_INSTALL_FALLBACK_SECONDS:-600}"
30
+
31
+ KS_LOG=/tmp/ks-pre.log
32
+ READY_FLAG=/tmp/.underpost-ssh-ready-posted
33
+ TRIGGER_FILE=/tmp/.underpost-install-trigger
34
+ INSTALL_LOCK=/tmp/.underpost-install-running
35
+ INSTALL_DONE=/tmp/.underpost-install-done
36
+ INSTALLER=/usr/local/bin/underpost-install.sh
37
+ TARGET_MNT=/mnt/sysimage-underpost
38
+
39
+ log() { echo "$(date): $*" | tee -a "$KS_LOG"; }
40
+
41
+ # Reference feedback on the physical/serial console. Use printf with \r\n so
42
+ # lines render correctly on serial and physical terminals. Best-effort: never
43
+ # fails if /dev/console is unavailable.
44
+ console_log() { printf "[underpost] %s\r\n" "$*" > /dev/console 2>/dev/null || true; }
45
+
46
+ # ---------------------------------------------------------------------------
47
+ # 1. Root password (emergency console fallback only; SSH stays key-only)
48
+ # ---------------------------------------------------------------------------
49
+ if [ -n "$ROOT_PASS" ]; then
50
+ echo "root:$ROOT_PASS" | chpasswd 2>/dev/null || \
51
+ echo "$ROOT_PASS" | passwd --stdin root 2>/dev/null || {
52
+ HASH=$(python3 -c "import crypt; print(crypt.crypt('$ROOT_PASS', crypt.mksalt(crypt.METHOD_SHA512)))" 2>/dev/null || \
53
+ openssl passwd -6 "$ROOT_PASS" 2>/dev/null)
54
+ [ -n "$HASH" ] && sed -i "s|^root:[^:]*:|root:$HASH:|" /etc/shadow 2>/dev/null
55
+ }
56
+ fi
57
+
58
+ if [ -n "$AUTHORIZED_KEYS" ]; then
59
+ mkdir -p /root/.ssh && chmod 700 /root/.ssh
60
+ echo "$AUTHORIZED_KEYS" > /root/.ssh/authorized_keys
61
+ chmod 600 /root/.ssh/authorized_keys
62
+ fi
63
+
64
+ # ---------------------------------------------------------------------------
65
+ # 2. Admin user (parity with previous behavior)
66
+ # ---------------------------------------------------------------------------
67
+ if command -v useradd >/dev/null 2>&1; then
68
+ useradd -m -G wheel "$ADMIN_USER" 2>/dev/null || true
69
+ else
70
+ NEXT_UID=$(awk -F: 'BEGIN{max=999} $3>max && $3<60000{max=$3} END{print max+1}' /etc/passwd 2>/dev/null || echo 1001)
71
+ if ! grep -q "^$ADMIN_USER:" /etc/passwd 2>/dev/null; then
72
+ echo "$ADMIN_USER:x:$NEXT_UID:$NEXT_UID:$ADMIN_USER:/home/$ADMIN_USER:/bin/bash" >> /etc/passwd
73
+ echo "$ADMIN_USER:x:$NEXT_UID:" >> /etc/group 2>/dev/null
74
+ echo "$ADMIN_USER:!:19000:0:99999:7:::" >> /etc/shadow 2>/dev/null
75
+ mkdir -p /home/$ADMIN_USER
76
+ fi
77
+ fi
78
+
79
+ if [ -n "$ADMIN_PASS" ]; then
80
+ echo "$ADMIN_USER:$ADMIN_PASS" | chpasswd 2>/dev/null || \
81
+ echo "$ADMIN_PASS" | passwd --stdin "$ADMIN_USER" 2>/dev/null || {
82
+ HASH=$(python3 -c "import crypt; print(crypt.crypt('$ADMIN_PASS', crypt.mksalt(crypt.METHOD_SHA512)))" 2>/dev/null || \
83
+ openssl passwd -6 "$ADMIN_PASS" 2>/dev/null)
84
+ [ -n "$HASH" ] && sed -i "s|^$ADMIN_USER:[^:]*:|$ADMIN_USER:$HASH:|" /etc/shadow 2>/dev/null
85
+ }
86
+ fi
87
+
88
+ if [ -n "$AUTHORIZED_KEYS" ]; then
89
+ mkdir -p /home/$ADMIN_USER/.ssh && chmod 700 /home/$ADMIN_USER/.ssh
90
+ echo "$AUTHORIZED_KEYS" > /home/$ADMIN_USER/.ssh/authorized_keys
91
+ chmod 600 /home/$ADMIN_USER/.ssh/authorized_keys
92
+ chown -R $ADMIN_USER:$ADMIN_USER /home/$ADMIN_USER/.ssh 2>/dev/null || true
93
+ fi
94
+
95
+ if [ -d /etc/sudoers.d ]; then
96
+ echo "$ADMIN_USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$ADMIN_USER
97
+ chmod 0440 /etc/sudoers.d/$ADMIN_USER
98
+ elif [ -f /etc/sudoers ]; then
99
+ echo "$ADMIN_USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
100
+ fi
101
+
102
+ # ---------------------------------------------------------------------------
103
+ # 3. Configure sshd for key-only automation
104
+ # ---------------------------------------------------------------------------
105
+ log "[sshd] Starting SSH configuration..."
106
+
107
+ mkdir -p /etc/ssh /root/.ssh /var/lib/anaconda/ssh /run/install/ssh
108
+ chmod 755 /etc/ssh
109
+ chmod 700 /root/.ssh
110
+ chmod 700 /var/lib/anaconda/ssh 2>/dev/null || true
111
+ chmod 700 /run/install/ssh 2>/dev/null || true
112
+
113
+ for KEY_DEST in \
114
+ /root/.ssh/authorized_keys \
115
+ /var/lib/anaconda/ssh/authorized_keys \
116
+ /run/install/ssh/authorized_keys; do
117
+ mkdir -p "$(dirname "$KEY_DEST")"
118
+ chmod 700 "$(dirname "$KEY_DEST")" 2>/dev/null || true
119
+ if [ -n "$AUTHORIZED_KEYS" ]; then
120
+ echo "$AUTHORIZED_KEYS" > "$KEY_DEST"
121
+ chmod 600 "$KEY_DEST"
122
+ chown root:root "$KEY_DEST" 2>/dev/null || true
123
+ log "[sshd] Wrote authorized_keys to $KEY_DEST"
124
+ fi
125
+ done
126
+
127
+ if [ -n "$AUTHORIZED_KEYS" ] && [ -n "$ADMIN_USER" ]; then
128
+ mkdir -p "/home/$ADMIN_USER/.ssh"
129
+ chmod 700 "/home/$ADMIN_USER/.ssh"
130
+ echo "$AUTHORIZED_KEYS" > "/home/$ADMIN_USER/.ssh/authorized_keys"
131
+ chmod 600 "/home/$ADMIN_USER/.ssh/authorized_keys"
132
+ chown -R "$ADMIN_USER:$ADMIN_USER" "/home/$ADMIN_USER/.ssh" 2>/dev/null || true
133
+ log "[sshd] Wrote authorized_keys to /home/$ADMIN_USER/.ssh/authorized_keys"
134
+ fi
135
+
136
+ # Key-only when keys are present; fall back to password auth only if no key was
137
+ # injected (so automation is never fully locked out). Root login is permitted
138
+ # strictly via authorized keys (prohibit-password) for non-interactive batch
139
+ # command execution from the controller.
140
+ if [ -n "$AUTHORIZED_KEYS" ]; then
141
+ SSHD_PASSWORD_AUTH="no"
142
+ SSHD_PERMIT_ROOT="prohibit-password"
143
+ SSHD_KBD_INTERACTIVE="no"
144
+ log "[sshd] authorized_keys present -> key-only mode (PasswordAuthentication no, PermitRootLogin prohibit-password)"
145
+ else
146
+ SSHD_PASSWORD_AUTH="yes"
147
+ SSHD_PERMIT_ROOT="yes"
148
+ SSHD_KBD_INTERACTIVE="yes"
149
+ log "[sshd] WARNING: no authorized_keys injected -> falling back to password auth"
150
+ fi
151
+
152
+ cat > /etc/ssh/sshd_config << SSHEOF
153
+ Port ${SSH_PORT}
154
+ Protocol 2
155
+ HostKey /etc/ssh/ssh_host_rsa_key
156
+ HostKey /etc/ssh/ssh_host_ecdsa_key
157
+ HostKey /etc/ssh/ssh_host_ed25519_key
158
+ SyslogFacility AUTH
159
+ LogLevel INFO
160
+ LoginGraceTime 120
161
+ PermitRootLogin ${SSHD_PERMIT_ROOT}
162
+ StrictModes no
163
+ PubkeyAuthentication yes
164
+ AuthorizedKeysFile /root/.ssh/authorized_keys /var/lib/anaconda/ssh/authorized_keys /run/install/ssh/authorized_keys .ssh/authorized_keys
165
+ IgnoreRhosts yes
166
+ HostbasedAuthentication no
167
+ PermitEmptyPasswords no
168
+ PasswordAuthentication ${SSHD_PASSWORD_AUTH}
169
+ ChallengeResponseAuthentication ${SSHD_KBD_INTERACTIVE}
170
+ KbdInteractiveAuthentication ${SSHD_KBD_INTERACTIVE}
171
+ UsePAM no
172
+ X11Forwarding no
173
+ PrintMotd no
174
+ TCPKeepAlive yes
175
+ AcceptEnv LANG LC_*
176
+ Subsystem sftp /usr/libexec/openssh/sftp-server
177
+ UseDNS no
178
+ AllowTcpForwarding yes
179
+ ClientAliveInterval 30
180
+ ClientAliveCountMax 3
181
+ SSHEOF
182
+
183
+ if [ -d /etc/ssh/sshd_config.d ]; then
184
+ rm -f /etc/ssh/sshd_config.d/*.conf 2>/dev/null || true
185
+ fi
186
+
187
+ log "[sshd] Checking/Generating SSH host keys..."
188
+
189
+ _generate_host_key() {
190
+ local TYPE=$1
191
+ local FILE=$2
192
+ local BITS=$3
193
+
194
+ if [ -f "$FILE" ]; then
195
+ log "[sshd] Host key $FILE already exists, skipping."
196
+ return 0
197
+ fi
198
+
199
+ log "[sshd] Generating $TYPE host key: $FILE ..."
200
+
201
+ if command -v ssh-keygen >/dev/null 2>&1; then
202
+ ssh-keygen -t "$TYPE" -f "$FILE" -N "" >> "$KS_LOG" 2>&1
203
+ [ -f "$FILE" ] && { log "[sshd] ssh-keygen succeeded for $TYPE"; return 0; }
204
+ fi
205
+
206
+ if command -v openssl >/dev/null 2>&1; then
207
+ case "$TYPE" in
208
+ rsa) openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:${BITS:-2048} -out "$FILE" >> "$KS_LOG" 2>&1 ;;
209
+ ecdsa) openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out "$FILE" >> "$KS_LOG" 2>&1 ;;
210
+ ed25519) openssl genpkey -algorithm ED25519 -out "$FILE" >> "$KS_LOG" 2>&1 ;;
211
+ esac
212
+ openssl pkey -in "$FILE" -pubout > "${FILE}.pub" 2>> "$KS_LOG"
213
+ [ -f "$FILE" ] && { log "[sshd] openssl succeeded for $TYPE"; return 0; }
214
+ fi
215
+
216
+ log "[sshd] WARNING: key generation fallback for $TYPE (placeholder)"
217
+ dd if=/dev/urandom bs=1024 count=4 of="$FILE" 2>/dev/null
218
+ echo "placeholder public key" > "${FILE}.pub"
219
+ [ -f "$FILE" ]
220
+ }
221
+
222
+ _generate_host_key rsa /etc/ssh/ssh_host_rsa_key 2048
223
+ _generate_host_key ecdsa /etc/ssh/ssh_host_ecdsa_key 256
224
+ _generate_host_key ed25519 /etc/ssh/ssh_host_ed25519_key 256
225
+
226
+ chmod 600 /etc/ssh/ssh_host_*_key 2>/dev/null || true
227
+ chmod 644 /etc/ssh/ssh_host_*_key.pub 2>/dev/null || true
228
+
229
+ log "[sshd] Restarting sshd to apply key-only config..."
230
+ if command -v systemctl >/dev/null 2>&1; then
231
+ systemctl restart sshd 2>/dev/null || systemctl restart sshd.service 2>/dev/null || true
232
+ fi
233
+ if ! pidof sshd >/dev/null 2>&1; then
234
+ SSH_OLD_PID=$(pidof sshd 2>/dev/null | awk '{print $1}')
235
+ [ -n "$SSH_OLD_PID" ] && { kill "$SSH_OLD_PID" 2>/dev/null || true; sleep 1; }
236
+ /usr/sbin/sshd >> "$KS_LOG" 2>&1 || sshd >> "$KS_LOG" 2>&1 || true
237
+ fi
238
+ pidof sshd >/dev/null 2>&1 && log "[sshd] sshd running (pid: $(pidof sshd))" || log "[sshd] WARNING: sshd not running"
239
+
240
+ # Disable firewall so the controller can reach sshd / the install can fetch packages.
241
+ if command -v systemctl >/dev/null 2>&1; then
242
+ systemctl stop firewalld 2>/dev/null || systemctl stop iptables 2>/dev/null || true
243
+ systemctl disable firewalld 2>/dev/null || systemctl disable iptables 2>/dev/null || true
244
+ fi
245
+ firewall-cmd --set-default-zone=trusted 2>/dev/null || true
246
+ iptables -F 2>/dev/null || true
247
+ ip6tables -F 2>/dev/null || true
248
+
249
+ # ---------------------------------------------------------------------------
250
+ # 4. dnf repos (used by the live environment for the installer's package pull)
251
+ # ---------------------------------------------------------------------------
252
+ mkdir -p /var/lib/rpm /var/cache/dnf /var/log/dnf /etc/yum.repos.d /etc/pki/rpm-gpg /etc/dnf/vars
253
+ echo "9" > /etc/dnf/vars/releasever
254
+
255
+ if ! grep -q "^VERSION_ID=" /etc/os-release 2>/dev/null; then
256
+ cat > /etc/os-release << 'OSREL'
257
+ NAME="Rocky Linux"
258
+ VERSION="9"
259
+ ID="rocky"
260
+ ID_LIKE="rhel centos fedora"
261
+ VERSION_ID="9"
262
+ PLATFORM_ID="platform:el9"
263
+ PRETTY_NAME="Rocky Linux 9 (Ephemeral Anaconda)"
264
+ ANSI_COLOR="0;32"
265
+ HOME_URL="https://rockylinux.org/"
266
+ OSREL
267
+ fi
268
+
269
+ [ ! -f /etc/system-release ] && echo "Rocky Linux release 9 (Ephemeral)" > /etc/system-release
270
+
271
+ REPO_ARCH=$(uname -m)
272
+
273
+ rpm --import https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9 2>/dev/null || \
274
+ curl -fsSL https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9 -o /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 2>/dev/null || true
275
+
276
+ cat > /etc/yum.repos.d/rocky-baseos.repo << REPOEOF
277
+ [baseos]
278
+ name=Rocky Linux 9 - BaseOS
279
+ baseurl=http://dl.rockylinux.org/pub/rocky/9/BaseOS/$REPO_ARCH/os/
280
+ gpgcheck=1
281
+ enabled=1
282
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
283
+ https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
284
+ skip_if_unavailable=1
285
+ REPOEOF
286
+
287
+ cat > /etc/yum.repos.d/rocky-appstream.repo << REPOEOF2
288
+ [appstream]
289
+ name=Rocky Linux 9 - AppStream
290
+ baseurl=http://dl.rockylinux.org/pub/rocky/9/AppStream/$REPO_ARCH/os/
291
+ gpgcheck=1
292
+ enabled=1
293
+ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
294
+ https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-9
295
+ skip_if_unavailable=1
296
+ REPOEOF2
297
+
298
+ # ---------------------------------------------------------------------------
299
+ # 5. Bootstrap status POST helper (async, idempotent per stage, retry+backoff)
300
+ # ---------------------------------------------------------------------------
301
+ detect_ip() {
302
+ local ip=""
303
+ ip=$(ip addr show 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1 | head -1)
304
+ [ -z "$ip" ] && ip=$(hostname -I 2>/dev/null | awk '{print $1}')
305
+ [ -z "$ip" ] && ip=$(grep -oP '32 host \K[0-9.]+' /proc/net/fib_trie 2>/dev/null | grep -v '127.0.0.1' | head -1)
306
+ [ -z "$ip" ] && ip="UNKNOWN"
307
+ echo "$ip"
308
+ }
309
+
310
+ detect_mac() {
311
+ local iface
312
+ iface=$(ip -o link show up 2>/dev/null | awk -F': ' '$2!="lo"{print $2; exit}')
313
+ [ -n "$iface" ] && cat "/sys/class/net/$iface/address" 2>/dev/null || echo "UNKNOWN"
314
+ }
315
+
316
+ detect_vendor_model() {
317
+ local vendor product
318
+ vendor=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null | tr -d '\n')
319
+ product=$(cat /sys/class/dmi/id/product_name 2>/dev/null | tr -d '\n')
320
+ echo "${vendor} ${product}" | sed 's/^ *//;s/ *$//'
321
+ }
322
+
323
+ # Pure-bash HTTP POST over /dev/tcp. Last-resort transport when neither curl nor
324
+ # wget is present in the minimal Anaconda %pre environment.
325
+ _raw_http_post() {
326
+ local url="$1" body="$2"
327
+ local rest host port path
328
+ rest="${url#http://}"
329
+ path="/${rest#*/}"
330
+ rest="${rest%%/*}"
331
+ host="${rest%%:*}"
332
+ port="${rest##*:}"
333
+ [ "$host" = "$port" ] && port=80
334
+ exec 3<>"/dev/tcp/${host}/${port}" 2>/dev/null || return 1
335
+ printf 'POST %s HTTP/1.0\r\nHost: %s\r\nContent-Type: application/json\r\nContent-Length: %s\r\nConnection: close\r\n\r\n%s' \
336
+ "$path" "$host" "${#body}" "$body" >&3 2>/dev/null || { exec 3>&- 2>/dev/null; return 1; }
337
+ # Read (and discard) the response so the server flushes; ignore failures.
338
+ timeout 8 cat <&3 >/dev/null 2>&1
339
+ exec 3>&- 2>/dev/null
340
+ return 0
341
+ }
342
+
343
+ # post_status <stage> [extra_json_fields]
344
+ # Posts a lifecycle event to ${BOOTSTRAP_URL}/status. Tries curl, then wget, then
345
+ # a raw /dev/tcp HTTP POST so a missing http client never silently drops events.
346
+ # Retries with backoff but never blocks installation forever (capped attempts).
347
+ post_status() {
348
+ local stage="$1"; shift
349
+ local extra="$1"
350
+ if [ -z "$BOOTSTRAP_URL" ]; then
351
+ log "[post] BOOTSTRAP_URL unset, skipping stage=$stage"
352
+ return 0
353
+ fi
354
+
355
+ local ip mac model ts payload url
356
+ ip=$(detect_ip)
357
+ mac=$(detect_mac)
358
+ model=$(detect_vendor_model)
359
+ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
360
+ payload="{\"stage\":\"${stage}\",\"workflowId\":\"${WORKFLOW_ID}\",\"hostname\":\"${TARGET_HOSTNAME}\",\"systemId\":\"${SYSTEM_ID}\",\"ip\":\"${ip}\",\"mac\":\"${mac}\",\"sshPort\":${SSH_PORT},\"hardware\":\"${model}\",\"timestamp\":\"${ts}\"${extra:+,${extra}}}"
361
+ url="${BOOTSTRAP_URL%/}/status"
362
+
363
+ # Reference feedback on the physical console for every lifecycle stage.
364
+ console_log "stage=${stage} ip=${ip}${extra:+ ${extra}}"
365
+
366
+ log "[post] stage=$stage -> $url (curl=$(command -v curl >/dev/null 2>&1 && echo y || echo n) wget=$(command -v wget >/dev/null 2>&1 && echo y || echo n))"
367
+ log "[post] payload=$payload"
368
+
369
+ local attempt=1 max=4 delay=3
370
+ while [ "$attempt" -le "$max" ]; do
371
+ if command -v curl >/dev/null 2>&1 && \
372
+ curl -fsS -m 10 -X POST -H 'Content-Type: application/json' -d "$payload" "$url" >> "$KS_LOG" 2>&1; then
373
+ log "[post] stage=$stage delivered via curl (attempt $attempt)"
374
+ return 0
375
+ fi
376
+ if command -v wget >/dev/null 2>&1 && \
377
+ wget -q -T 10 -O - --header='Content-Type: application/json' --post-data="$payload" "$url" >> "$KS_LOG" 2>&1; then
378
+ log "[post] stage=$stage delivered via wget (attempt $attempt)"
379
+ return 0
380
+ fi
381
+ if _raw_http_post "$url" "$payload"; then
382
+ log "[post] stage=$stage delivered via /dev/tcp (attempt $attempt)"
383
+ return 0
384
+ fi
385
+ log "[post] stage=$stage attempt $attempt/$max failed; retrying in ${delay}s"
386
+ sleep "$delay"
387
+ delay=$((delay * 2))
388
+ attempt=$((attempt + 1))
389
+ done
390
+ log "[post] stage=$stage giving up after $max attempts (non-fatal)"
391
+ return 1
392
+ }
393
+
394
+ # Early heartbeat: announce the ephemeral runtime is up and that %pre reached the
395
+ # networking/POST stage. If even this never reaches the controller, the problem
396
+ # is transport/network — not disk detection or sshd.
397
+ post_status "ephemeral-boot" "\"detail\":\"%pre reached network/post stage\""
398
+
399
+ # ---------------------------------------------------------------------------
400
+ # 6. Safe install-disk detection for a real physical machine
401
+ # ---------------------------------------------------------------------------
402
+ # Rules (deterministic):
403
+ # - honor INSTALL_DISK_HINT if it is a valid block device
404
+ # - only whole disks (TYPE=disk), writable (RO=0), non-removable (RM=0)
405
+ # - skip USB-attached media (TRAN=usb) and zram/loop/ram devices
406
+ # - skip the device backing the live/ephemeral root, if any is disk-backed
407
+ # - among the remaining, prefer internal bus order (nvme > sata/sas) then
408
+ # largest size, and pick the smallest stable /dev/disk/by-id name for it
409
+ detect_install_disk() {
410
+ if [ -n "$INSTALL_DISK_HINT" ] && [ -b "$INSTALL_DISK_HINT" ]; then
411
+ echo "$INSTALL_DISK_HINT"
412
+ return 0
413
+ fi
414
+
415
+ # Device currently backing the live root filesystem (avoid wiping ourselves).
416
+ local live_src live_disk=""
417
+ live_src=$(findmnt -n -o SOURCE / 2>/dev/null)
418
+ if [ -n "$live_src" ] && [ -b "$live_src" ]; then
419
+ live_disk=$(lsblk -no PKNAME "$live_src" 2>/dev/null | head -1)
420
+ [ -z "$live_disk" ] && live_disk=$(basename "$live_src")
421
+ fi
422
+
423
+ # Emit "score name size" per candidate, sort, take the top.
424
+ local best=""
425
+ best=$(lsblk -dn -o NAME,TYPE,SIZE,RM,RO,TRAN -b 2>/dev/null | while read -r name type size rm ro tran; do
426
+ [ "$type" = "disk" ] || continue
427
+ [ "$ro" = "0" ] || continue
428
+ [ "$rm" = "0" ] || continue
429
+ case "$name" in
430
+ loop*|ram*|zram*|sr*|fd*) continue ;;
431
+ esac
432
+ [ "$tran" = "usb" ] && continue
433
+ [ -n "$live_disk" ] && [ "$name" = "$live_disk" ] && continue
434
+
435
+ # Bus preference weight (higher = preferred), then size as tiebreaker.
436
+ local weight=0
437
+ case "$tran" in
438
+ nvme) weight=3 ;;
439
+ sata|sas|ata) weight=2 ;;
440
+ *) weight=1 ;;
441
+ esac
442
+ # score = weight * 1e15 + size ; keeps weight dominant, size as tiebreak
443
+ printf '%d %s\n' "$(( weight * 1000000000000000 + ${size:-0} ))" "/dev/$name"
444
+ done | sort -rn | head -1 | awk '{print $2}')
445
+
446
+ [ -z "$best" ] && return 1
447
+
448
+ # Prefer a stable /dev/disk/by-id symlink for the chosen device.
449
+ local byid
450
+ byid=$(for l in /dev/disk/by-id/*; do
451
+ [ -e "$l" ] || continue
452
+ case "$l" in *-part*) continue ;; esac
453
+ if [ "$(readlink -f "$l")" = "$(readlink -f "$best")" ]; then
454
+ echo "$l"
455
+ fi
456
+ done 2>/dev/null | grep -v '/wwn-' | head -1)
457
+
458
+ [ -n "$byid" ] && echo "$byid" || echo "$best"
459
+ }
460
+
461
+ # ---------------------------------------------------------------------------
462
+ # 7. Write the unattended installer (run by the controller over SSH, or by the
463
+ # AUTO_INSTALL fallback). It detects the disk, installs Rocky 9, posts
464
+ # completion, and reboots into the deployed OS.
465
+ # ---------------------------------------------------------------------------
466
+ mkdir -p /usr/local/bin
467
+ cat > "$INSTALLER" << INSTALLEOF
468
+ #!/bin/bash
469
+ # Underpost unattended Rocky Linux 9 installer (runs inside the ephemeral env).
470
+ set +e
471
+
472
+ KS_LOG="$KS_LOG"
473
+ INSTALL_LOCK="$INSTALL_LOCK"
474
+ INSTALL_DONE="$INSTALL_DONE"
475
+ TARGET_MNT="$TARGET_MNT"
476
+ AUTHORIZED_KEYS='$AUTHORIZED_KEYS'
477
+ ADMIN_USER='$ADMIN_USER'
478
+ DEPLOY_USER='$DEPLOY_USER'
479
+ TARGET_HOSTNAME='$TARGET_HOSTNAME'
480
+ NET_IP='$NET_IP'
481
+ NET_PREFIX='$NET_PREFIX'
482
+ NET_GATEWAY='$NET_GATEWAY'
483
+ NET_DNS='$NET_DNS'
484
+ TIMEZONE='$TIMEZONE'
485
+ KEYBOARD_LAYOUT='$KEYBOARD_LAYOUT'
486
+ CHRONY_CONF_PATH='$CHRONY_CONF_PATH'
487
+ # Passwords are carried base64-encoded so any character survives intact. Decoding
488
+ # tries base64 then python3 so a minimal environment never yields empty passwords.
489
+ ks_b64d() { printf %s "\$1" | base64 -d 2>/dev/null || printf %s "\$1" | python3 -c 'import sys,base64;sys.stdout.buffer.write(base64.b64decode(sys.stdin.read().strip()))' 2>/dev/null; }
490
+ ROOT_PASS_B64='$ROOT_PASS_B64'
491
+ ADMIN_PASS_B64='$ADMIN_PASS_B64'
492
+ DEPLOY_PASS_B64='$DEPLOY_PASS_B64'
493
+ ROOT_PASS="\$(ks_b64d "\$ROOT_PASS_B64")"
494
+ ADMIN_PASS="\$(ks_b64d "\$ADMIN_PASS_B64")"
495
+ DEPLOY_PASS="\$(ks_b64d "\$DEPLOY_PASS_B64")"
496
+ [ -z "\$ADMIN_PASS" ] && ADMIN_PASS="\$ROOT_PASS"
497
+ [ -z "\$DEPLOY_PASS" ] && DEPLOY_PASS="\$ROOT_PASS"
498
+
499
+ ilog() {
500
+ echo "\$(date): [install] \$*" | tee -a "\$KS_LOG"
501
+ printf "[underpost-install] %s\r\n" "\$*" > /dev/console 2>/dev/null || true
502
+ }
503
+
504
+ # Prove the installer actually launched (distinguishes "never started" from
505
+ # "started and exited early"). Posted before any guard so it always fires once.
506
+ ilog "installer process started (pid \$\$)"
507
+ post_status "install-start" "\"detail\":\"installer launched\""
508
+
509
+ # Single-flight guard.
510
+ if [ -f "\$INSTALL_LOCK" ]; then
511
+ ilog "installer already running (lock present), exiting"
512
+ exit 0
513
+ fi
514
+ if [ -f "\$INSTALL_DONE" ]; then
515
+ ilog "install already completed, exiting"
516
+ exit 0
517
+ fi
518
+ touch "\$INSTALL_LOCK"
519
+
520
+ post_status "installing" "\"detail\":\"partitioning\""
521
+
522
+ DISK="\$(detect_install_disk)"
523
+ if [ -z "\$DISK" ] || [ ! -b "\$DISK" ]; then
524
+ ilog "FATAL: no valid install disk detected"
525
+ post_status "failed" "\"detail\":\"no install disk detected\""
526
+ rm -f "\$INSTALL_LOCK"
527
+ exit 1
528
+ fi
529
+ REAL_DISK="\$(readlink -f "\$DISK")"
530
+ ilog "Selected install disk: \$DISK (\$REAL_DISK)"
531
+ post_status "installing" "\"detail\":\"target \$REAL_DISK\",\"disk\":\"\$REAL_DISK\""
532
+
533
+ # Detect firmware mode.
534
+ if [ -d /sys/firmware/efi ]; then
535
+ FW="uefi"
536
+ else
537
+ FW="bios"
538
+ fi
539
+ ilog "Firmware mode: \$FW"
540
+
541
+ # Partition naming helper (nvme0n1p1 vs sda1).
542
+ part() {
543
+ case "\$REAL_DISK" in
544
+ *[0-9]) echo "\${REAL_DISK}p\$1" ;;
545
+ *) echo "\${REAL_DISK}\$1" ;;
546
+ esac
547
+ }
548
+
549
+ ilog "Wiping and partitioning \$REAL_DISK ..."
550
+ umount -R "\$TARGET_MNT" 2>/dev/null || true
551
+ swapoff -a 2>/dev/null || true
552
+ wipefs -a "\$REAL_DISK" >> "\$KS_LOG" 2>&1
553
+ sgdisk --zap-all "\$REAL_DISK" >> "\$KS_LOG" 2>&1 || dd if=/dev/zero of="\$REAL_DISK" bs=1M count=10 2>/dev/null
554
+
555
+ if [ "\$FW" = "uefi" ]; then
556
+ sgdisk -n 1:0:+600M -t 1:ef00 -c 1:"EFI System" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
557
+ sgdisk -n 2:0:+1024M -t 2:8300 -c 2:"boot" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
558
+ sgdisk -n 3:0:0 -t 3:8300 -c 3:"root" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
559
+ EFI_PART="\$(part 1)"; BOOT_PART="\$(part 2)"; ROOT_PART="\$(part 3)"
560
+ else
561
+ sgdisk -n 1:0:+2M -t 1:ef02 -c 1:"BIOS boot" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
562
+ sgdisk -n 2:0:+1024M -t 2:8300 -c 2:"boot" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
563
+ sgdisk -n 3:0:0 -t 3:8300 -c 3:"root" "\$REAL_DISK" >> "\$KS_LOG" 2>&1
564
+ BOOT_PART="\$(part 2)"; ROOT_PART="\$(part 3)"
565
+ fi
566
+
567
+ partprobe "\$REAL_DISK" >> "\$KS_LOG" 2>&1 || true
568
+ udevadm settle 2>/dev/null || sleep 3
569
+
570
+ ilog "Creating filesystems ..."
571
+ [ "\$FW" = "uefi" ] && mkfs.vfat -F32 "\$EFI_PART" >> "\$KS_LOG" 2>&1
572
+ mkfs.xfs -f "\$BOOT_PART" >> "\$KS_LOG" 2>&1
573
+ mkfs.xfs -f "\$ROOT_PART" >> "\$KS_LOG" 2>&1
574
+
575
+ ilog "Mounting target ..."
576
+ mkdir -p "\$TARGET_MNT"
577
+ mount "\$ROOT_PART" "\$TARGET_MNT" || { ilog "FATAL: mount root failed"; post_status "failed" "\"detail\":\"mount root failed\""; rm -f "\$INSTALL_LOCK"; exit 1; }
578
+ mkdir -p "\$TARGET_MNT/boot"
579
+ mount "\$BOOT_PART" "\$TARGET_MNT/boot"
580
+ if [ "\$FW" = "uefi" ]; then
581
+ mkdir -p "\$TARGET_MNT/boot/efi"
582
+ mount "\$EFI_PART" "\$TARGET_MNT/boot/efi"
583
+ fi
584
+
585
+ post_status "installing" "\"detail\":\"installing packages\",\"disk\":\"\$REAL_DISK\""
586
+
587
+ ilog "Installing base packages with dnf --installroot ..."
588
+ PKGS="@core kernel grub2-tools openssh-server NetworkManager chrony dracut-config-generic rocky-release"
589
+ if [ "\$FW" = "uefi" ]; then
590
+ PKGS="\$PKGS grub2-efi-x64 shim-x64 efibootmgr"
591
+ else
592
+ PKGS="\$PKGS grub2-pc"
593
+ fi
594
+
595
+ dnf -y --installroot="\$TARGET_MNT" --releasever=9 \
596
+ --setopt=install_weak_deps=False --nogpgcheck \
597
+ install \$PKGS >> "\$KS_LOG" 2>&1
598
+ DNF_RC=\$?
599
+ if [ "\$DNF_RC" -ne 0 ]; then
600
+ ilog "FATAL: dnf install failed (rc=\$DNF_RC)"
601
+ post_status "failed" "\"detail\":\"dnf install rc=\$DNF_RC\""
602
+ rm -f "\$INSTALL_LOCK"
603
+ exit 1
604
+ fi
605
+
606
+ ilog "Generating fstab ..."
607
+ ROOT_UUID=\$(blkid -s UUID -o value "\$ROOT_PART")
608
+ BOOT_UUID=\$(blkid -s UUID -o value "\$BOOT_PART")
609
+ {
610
+ echo "UUID=\$ROOT_UUID / xfs defaults 0 0"
611
+ echo "UUID=\$BOOT_UUID /boot xfs defaults 0 0"
612
+ if [ "\$FW" = "uefi" ]; then
613
+ EFI_UUID=\$(blkid -s UUID -o value "\$EFI_PART")
614
+ echo "UUID=\$EFI_UUID /boot/efi vfat umask=0077,shortname=winnt 0 2"
615
+ fi
616
+ } > "\$TARGET_MNT/etc/fstab"
617
+
618
+ # Bind mounts for chroot.
619
+ for d in dev proc sys run; do mount --bind /\$d "\$TARGET_MNT/\$d"; done
620
+
621
+ ilog "Configuring installed system (hostname, network, ssh, users) ..."
622
+ echo "\${TARGET_HOSTNAME:-rocky9}" > "\$TARGET_MNT/etc/hostname"
623
+
624
+ chroot "\$TARGET_MNT" /bin/bash -s << CHROOTEOF >> "\$KS_LOG" 2>&1
625
+ set +e
626
+ systemctl enable sshd NetworkManager chronyd 2>/dev/null
627
+
628
+ # SELinux -> permissive in the DEPLOYED OS. Critical: with SELinux enforcing on
629
+ # first boot, files written from this installer chroot (authorized_keys, home
630
+ # dirs) carry the wrong security context, so sshd drops sessions ("Connection
631
+ # reset by peer") and PAM can block console logins. Permissive ignores contexts
632
+ # (no relabel reboot needed) and matches what kubeadm/cluster.js expect.
633
+ sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config 2>/dev/null || true
634
+
635
+ # Ensure sshd host keys exist so sshd actually starts on first boot.
636
+ ssh-keygen -A 2>/dev/null || true
637
+
638
+ # Disable firewalld so the controller can reach sshd on first boot.
639
+ systemctl disable firewalld 2>/dev/null || true
640
+ systemctl mask firewalld 2>/dev/null || true
641
+
642
+ # Static networking bound to the primary wired NIC by MAC so the deployed OS is
643
+ # reachable at the same IP the commission used (NetworkManager keyfile).
644
+ if [ -n "\${NET_IP}" ]; then
645
+ PRIMARY_IF=\\\$(ls /sys/class/net | grep -E '^(en|eth)' | head -1)
646
+ PRIMARY_MAC=\\\$(cat /sys/class/net/\\\$PRIMARY_IF/address 2>/dev/null)
647
+ mkdir -p /etc/NetworkManager/system-connections
648
+ NMFILE=/etc/NetworkManager/system-connections/underpost.nmconnection
649
+ {
650
+ echo "[connection]"
651
+ echo "id=underpost"
652
+ echo "type=ethernet"
653
+ echo "autoconnect=true"
654
+ echo "autoconnect-priority=999"
655
+ echo "[ethernet]"
656
+ [ -n "\\\$PRIMARY_MAC" ] && echo "mac-address=\\\$PRIMARY_MAC"
657
+ echo "[ipv4]"
658
+ echo "method=manual"
659
+ echo "addresses=\${NET_IP}/\${NET_PREFIX}"
660
+ echo "gateway=\${NET_GATEWAY}"
661
+ echo "dns=\${NET_DNS};"
662
+ echo "[ipv6]"
663
+ echo "method=ignore"
664
+ } > "\\\$NMFILE"
665
+ chmod 600 "\\\$NMFILE"
666
+ fi
667
+
668
+ # Timezone + NTP (chrony) for the deployed OS. Mirrors the Rocky branch of
669
+ # src/cli/system.js (rocky.timezone): localtime symlink, /etc/timezone, a chrony
670
+ # config with a local + public NTP pool, and chronyd enabled on boot.
671
+ if [ -n "\${TIMEZONE}" ]; then
672
+ ln -sf /usr/share/zoneinfo/\${TIMEZONE} /etc/localtime
673
+ echo "\${TIMEZONE}" > /etc/timezone
674
+ timedatectl set-timezone \${TIMEZONE} 2>/dev/null || true
675
+ {
676
+ echo "# Underpost-managed chrony configuration"
677
+ [ -n "\${NET_GATEWAY}" ] && echo "server \${NET_GATEWAY} iburst prefer"
678
+ echo "server 0.pool.ntp.org iburst"
679
+ echo "server 1.pool.ntp.org iburst"
680
+ echo "server 2.pool.ntp.org iburst"
681
+ echo "server 3.pool.ntp.org iburst"
682
+ echo "driftfile /var/lib/chrony/drift"
683
+ echo "makestep 1.0 3"
684
+ echo "rtcsync"
685
+ echo "logdir /var/log/chrony"
686
+ } > "\${CHRONY_CONF_PATH:-/etc/chrony.conf}"
687
+ systemctl enable chronyd 2>/dev/null || true
688
+ fi
689
+
690
+ # Keyboard layout + locale for the deployed OS. Mirrors the Rocky branch of
691
+ # src/cli/system.js (rocky.keyboard): vconsole.conf, locale.conf, X11 keymap.
692
+ if [ -n "\${KEYBOARD_LAYOUT}" ]; then
693
+ echo "KEYMAP=\${KEYBOARD_LAYOUT}" > /etc/vconsole.conf
694
+ echo "FONT=latarcyrheb-sun16" >> /etc/vconsole.conf
695
+ echo "LANG=en_US.UTF-8" > /etc/locale.conf
696
+ mkdir -p /etc/X11/xorg.conf.d
697
+ {
698
+ echo 'Section "InputClass"'
699
+ echo ' Identifier "system-keyboard"'
700
+ echo ' MatchIsKeyboard "on"'
701
+ echo ' Option "XkbLayout" "\${KEYBOARD_LAYOUT}"'
702
+ echo 'EndSection'
703
+ } > /etc/X11/xorg.conf.d/00-keyboard.conf
704
+ localectl set-keymap \${KEYBOARD_LAYOUT} 2>/dev/null || true
705
+ localectl set-x11-keymap \${KEYBOARD_LAYOUT} 2>/dev/null || true
706
+ fi
707
+
708
+ # Key-only SSH on the installed system.
709
+ mkdir -p /etc/ssh/sshd_config.d
710
+ cat > /etc/ssh/sshd_config.d/00-underpost.conf <<SSHDEOF
711
+ PermitRootLogin prohibit-password
712
+ PubkeyAuthentication yes
713
+ PasswordAuthentication no
714
+ SSHDEOF
715
+
716
+ # Create the admin login accounts. create_user <name> writes the authorized key,
717
+ # wheel membership and passwordless sudo. Passwords are applied after the chroot.
718
+ create_user() {
719
+ [ -z "\\\$1" ] && return 0
720
+ id "\\\$1" >/dev/null 2>&1 || useradd -m -G wheel "\\\$1"
721
+ usermod -aG wheel "\\\$1" 2>/dev/null || true
722
+ mkdir -p /home/\\\$1/.ssh && chmod 700 /home/\\\$1/.ssh
723
+ cat > /home/\\\$1/.ssh/authorized_keys <<KEYEOF
724
+ \${AUTHORIZED_KEYS}
725
+ KEYEOF
726
+ chmod 600 /home/\\\$1/.ssh/authorized_keys
727
+ chown -R "\\\$1:\\\$1" /home/\\\$1/.ssh
728
+ echo "\\\$1 ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/\\\$1
729
+ chmod 0440 /etc/sudoers.d/\\\$1
730
+ }
731
+
732
+ mkdir -p /root/.ssh && chmod 700 /root/.ssh
733
+ cat > /root/.ssh/authorized_keys <<KEYEOF3
734
+ \${AUTHORIZED_KEYS}
735
+ KEYEOF3
736
+ chmod 600 /root/.ssh/authorized_keys
737
+
738
+ create_user "\${ADMIN_USER}"
739
+ create_user "\${DEPLOY_USER}"
740
+
741
+ # Build initramfs for the installed kernel.
742
+ KVER=\\\$(ls /lib/modules | head -1)
743
+ [ -n "\\\$KVER" ] && dracut -f /boot/initramfs-\\\$KVER.img "\\\$KVER"
744
+ CHROOTEOF
745
+
746
+ # Set console passwords AFTER the chroot heredoc, from decoded installer vars.
747
+ # Primary path: pipe 'user:password' into 'chroot chpasswd' (keeps password
748
+ # characters out of any heredoc). Fallback: hash with openssl and apply via
749
+ # 'usermod -p' so a chpasswd/PAM quirk in the installroot never leaves an
750
+ # account locked. Verifies the shadow field is a real hash afterwards.
751
+ set_password() {
752
+ local u="\$1" p="\$2"
753
+ [ -z "\$u" ] || [ -z "\$p" ] && return 0
754
+ printf '%s:%s\n' "\$u" "\$p" | chroot "\$TARGET_MNT" chpasswd 2>>"\$KS_LOG"
755
+ local field
756
+ field=\$(chroot "\$TARGET_MNT" getent shadow "\$u" 2>/dev/null | cut -d: -f2)
757
+ case "\$field" in
758
+ '\$'*) ilog "\$u password set (chpasswd)"; return 0 ;;
759
+ esac
760
+ local hash
761
+ hash=\$(printf %s "\$p" | openssl passwd -6 -stdin 2>/dev/null)
762
+ if [ -n "\$hash" ]; then
763
+ chroot "\$TARGET_MNT" usermod -p "\$hash" "\$u" 2>>"\$KS_LOG" && ilog "\$u password set (openssl hash fallback)"
764
+ else
765
+ ilog "WARNING: failed to set password for \$u"
766
+ fi
767
+ }
768
+ set_password root "\$ROOT_PASS"
769
+ set_password "\$ADMIN_USER" "\$ADMIN_PASS"
770
+ set_password "\$DEPLOY_USER" "\$DEPLOY_PASS"
771
+
772
+ post_status "installing" "\"detail\":\"installing bootloader\",\"disk\":\"\$REAL_DISK\""
773
+
774
+ ilog "Installing bootloader (\$FW) on \$REAL_DISK ..."
775
+ if [ "\$FW" = "uefi" ]; then
776
+ chroot "\$TARGET_MNT" grub2-mkconfig -o /boot/grub2/grub.cfg >> "\$KS_LOG" 2>&1
777
+ chroot "\$TARGET_MNT" mkdir -p /boot/efi/EFI/rocky
778
+ chroot "\$TARGET_MNT" grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg >> "\$KS_LOG" 2>&1
779
+ # Drop any stale Rocky Linux UEFI entries to avoid duplicates.
780
+ for b in \$(chroot "\$TARGET_MNT" efibootmgr 2>/dev/null | awk '/Rocky Linux/{print substr(\$1,5,4)}'); do
781
+ chroot "\$TARGET_MNT" efibootmgr -b "\$b" -B >> "\$KS_LOG" 2>&1
782
+ done
783
+ # Create the boot entry (also prepends it to BootOrder).
784
+ chroot "\$TARGET_MNT" efibootmgr -c -d "\$REAL_DISK" -p 1 -L "Rocky Linux" -l "\\\\EFI\\\\rocky\\\\shimx64.efi" >> "\$KS_LOG" 2>&1
785
+ BOOT_RC=\$?
786
+ # Set BootNext so the immediate post-install reboot boots the DISK, not the
787
+ # USB iPXE installer — this overrides a USB-first firmware order for one boot,
788
+ # so no manual BIOS change is needed to land in the freshly installed OS.
789
+ NEW_BOOT=\$(chroot "\$TARGET_MNT" efibootmgr 2>/dev/null | awk '/Rocky Linux/{print substr(\$1,5,4); exit}')
790
+ if [ -n "\$NEW_BOOT" ]; then
791
+ chroot "\$TARGET_MNT" efibootmgr -n "\$NEW_BOOT" >> "\$KS_LOG" 2>&1
792
+ ilog "Set UEFI BootNext=\$NEW_BOOT (Rocky Linux on \$REAL_DISK); remove USB after this boot to stay on disk"
793
+ fi
794
+ else
795
+ chroot "\$TARGET_MNT" /bin/bash -c "grub2-install --target=i386-pc \$REAL_DISK && \
796
+ grub2-mkconfig -o /boot/grub2/grub.cfg" >> "\$KS_LOG" 2>&1
797
+ BOOT_RC=\$?
798
+ fi
799
+
800
+ # Teardown mounts.
801
+ for d in dev proc sys run; do umount -l "\$TARGET_MNT/\$d" 2>/dev/null; done
802
+ umount -R "\$TARGET_MNT" 2>/dev/null || true
803
+
804
+ if [ "\$BOOT_RC" -ne 0 ]; then
805
+ ilog "FATAL: bootloader install failed (rc=\$BOOT_RC)"
806
+ post_status "failed" "\"detail\":\"bootloader rc=\$BOOT_RC\""
807
+ rm -f "\$INSTALL_LOCK"
808
+ exit 1
809
+ fi
810
+
811
+ touch "\$INSTALL_DONE"
812
+ ilog "Install completed on \$REAL_DISK. Rebooting into deployed OS (BootNext set to disk)."
813
+ ilog "If it boots the USB again, remove the USB stick now — the OS is on \$REAL_DISK."
814
+ ilog "Console login: 'root', '\${ADMIN_USER}'\$([ -n "\$DEPLOY_USER" ] && echo " or '\$DEPLOY_USER'") (password \$([ -n "\$ROOT_PASS" ] && echo set || echo NOT-set)). SSH is key-only at \${NET_IP:-dhcp}."
815
+ post_status "completed" "\"detail\":\"install ok, rebooting into disk\",\"disk\":\"\$REAL_DISK\",\"loginUser\":\"\${ADMIN_USER}\",\"deployUser\":\"\${DEPLOY_USER}\",\"passwordSet\":\$([ -n "\$ROOT_PASS" ] && echo true || echo false),\"staticIp\":\"\${NET_IP}\",\"bootNext\":\"\${NEW_BOOT:-}\""
816
+ rm -f "\$INSTALL_LOCK"
817
+ sync
818
+ sleep 3
819
+ reboot -f || systemctl reboot || echo b > /proc/sysrq-trigger
820
+ INSTALLEOF
821
+ chmod +x "$INSTALLER"
822
+ log "[install] Wrote unattended installer to $INSTALLER"
823
+
824
+ # Export helpers used by the installer (it sources nothing; functions are
825
+ # re-declared above). The installer relies on post_status/detect_install_disk
826
+ # being defined in its own process, so embed minimal copies inline.
827
+ # To keep one source of truth, re-export them via a sourced fragment.
828
+ cat > /usr/local/bin/underpost-install-helpers.sh << HELPEREOF
829
+ $(declare -f log)
830
+ $(declare -f console_log)
831
+ $(declare -f detect_ip)
832
+ $(declare -f detect_mac)
833
+ $(declare -f detect_vendor_model)
834
+ $(declare -f post_status)
835
+ $(declare -f detect_install_disk)
836
+ BOOTSTRAP_URL='$BOOTSTRAP_URL'
837
+ WORKFLOW_ID='$WORKFLOW_ID'
838
+ SYSTEM_ID='$SYSTEM_ID'
839
+ TARGET_HOSTNAME='$TARGET_HOSTNAME'
840
+ SSH_PORT='$SSH_PORT'
841
+ INSTALL_DISK_HINT='$INSTALL_DISK_HINT'
842
+ HELPEREOF
843
+ # Prepend a source of the helpers into the installer so its post_status /
844
+ # detect_install_disk calls resolve.
845
+ sed -i "2i source /usr/local/bin/underpost-install-helpers.sh" "$INSTALLER"
846
+
847
+ # ---------------------------------------------------------------------------
848
+ # 8. Physical console banner + SSH-ready handshake
849
+ # ---------------------------------------------------------------------------
850
+ DETECTED_IP=$(detect_ip)
851
+
852
+ echo ""
853
+ echo "=============================================="
854
+ echo "Underpost: Ephemeral SSHD Setup Complete"
855
+ echo "=============================================="
856
+ echo "Root login: root (key-only: $([ -n "$AUTHORIZED_KEYS" ] && echo yes || echo no))"
857
+ echo "Admin user: $ADMIN_USER"
858
+ echo "SSH keys: $([ -n "$AUTHORIZED_KEYS" ] && echo 'configured' || echo 'NOT configured')"
859
+ echo "sshd status: $(pidof sshd >/dev/null 2>&1 && echo "running (pid $(pidof sshd))" || echo 'NOT running')"
860
+ echo "IP address: $DETECTED_IP"
861
+ echo "Installer: $INSTALLER"
862
+ echo "=============================================="
863
+
864
+ {
865
+ printf "\r\n"
866
+ printf "██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗\r\n"
867
+ printf "██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝\r\n"
868
+ printf "██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░\r\n"
869
+ printf "██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░\r\n"
870
+ printf "╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░\r\n"
871
+ printf "░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░\r\n"
872
+ printf "==============================================\r\n"
873
+ printf " Underpost Network Ephemeral Commissioning Active\r\n"
874
+ printf "==============================================\r\n"
875
+ printf " SSH as: root@%s -p %s (key-only)\r\n" "$DETECTED_IP" "$SSH_PORT"
876
+ printf " Stage: awaiting remote install trigger\r\n"
877
+ printf " Disk: auto-detect (hint: %s)\r\n" "${INSTALL_DISK_HINT:-none}"
878
+ printf "==============================================\r\n"
879
+ printf "\r\n"
880
+ } > /dev/console 2>/dev/null || true
881
+
882
+ # Best-effort check that sshd is accepting connections on the configured port.
883
+ # Reported as metadata in the ssh-ready event but does NOT gate the POST: the
884
+ # controller needs the announcement regardless, and inst.sshd may name/track the
885
+ # daemon in ways pidof misses.
886
+ ssh_is_ready() {
887
+ if command -v ss >/dev/null 2>&1; then
888
+ ss -lnt 2>/dev/null | grep -q ":${SSH_PORT} " && return 0
889
+ fi
890
+ if command -v netstat >/dev/null 2>&1; then
891
+ netstat -lnt 2>/dev/null | grep -q ":${SSH_PORT} " && return 0
892
+ fi
893
+ timeout 3 bash -c "</dev/tcp/127.0.0.1/${SSH_PORT}" >/dev/null 2>&1
894
+ }
895
+
896
+ # Give sshd a brief window to come up, but never block the announcement.
897
+ for _ in $(seq 1 15); do
898
+ ssh_is_ready && break
899
+ sleep 2
900
+ done
901
+
902
+ SSHD_LISTENING=$(ssh_is_ready && echo true || echo false)
903
+ SSHD_PID=$(pidof sshd 2>/dev/null | awk '{print $1}')
904
+ log "[ready] sshd_listening=${SSHD_LISTENING} sshd_pid=${SSHD_PID:-none} port=${SSH_PORT}"
905
+
906
+ # Idempotent: only POST ssh-ready once per boot/session. Posted unconditionally
907
+ # (best effort) so a strict readiness probe never swallows the handshake.
908
+ if [ ! -f "$READY_FLAG" ]; then
909
+ if post_status "ssh-ready" "\"detail\":\"ephemeral runtime ready\",\"sshdListening\":${SSHD_LISTENING},\"sshdPid\":\"${SSHD_PID:-}\",\"installer\":\"${INSTALLER}\""; then
910
+ touch "$READY_FLAG"
911
+ log "[ready] ssh-ready handshake posted"
912
+ else
913
+ log "[ready] ssh-ready POST failed; will retry in lifecycle loop"
914
+ fi
915
+ fi
916
+
917
+ # ---------------------------------------------------------------------------
918
+ # 9. Lifecycle wait loop
919
+ # - keep sshd alive (inst.sshd watchdog should also handle this)
920
+ # - run the installer when the controller drops a trigger file over SSH,
921
+ # e.g. ssh root@host 'touch /tmp/.underpost-install-trigger'
922
+ # or directly: ssh root@host '/usr/local/bin/underpost-install.sh'
923
+ # - AUTO_INSTALL fallback self-triggers after AUTO_INSTALL_FALLBACK_SECONDS
924
+ # ---------------------------------------------------------------------------
925
+ INSTALL_LOG=/tmp/underpost-install.log
926
+ LAUNCHED_FLAG=/tmp/.underpost-install-launched
927
+
928
+ # Launch the installer fully detached from this loop process via setsid + closed
929
+ # stdio, so it keeps running independently of any sshd session or signal. Guarded
930
+ # by LAUNCHED_FLAG so trigger + fallback never double-launch.
931
+ launch_installer() {
932
+ [ -f "$LAUNCHED_FLAG" ] && return 0
933
+ touch "$LAUNCHED_FLAG"
934
+ log "[loop] launching installer ($INSTALLER), log -> $INSTALL_LOG"
935
+ console_log "remote command received: starting disk install ($INSTALLER)"
936
+ if command -v setsid >/dev/null 2>&1; then
937
+ setsid bash "$INSTALLER" >> "$INSTALL_LOG" 2>&1 < /dev/null &
938
+ else
939
+ nohup bash "$INSTALLER" >> "$INSTALL_LOG" 2>&1 < /dev/null &
940
+ fi
941
+ }
942
+
943
+ START_TS=$(date +%s)
944
+ LOOP_N=0
945
+ while true; do
946
+ [ -f "$INSTALL_DONE" ] && { log "[loop] install done; idle"; sleep 60; continue; }
947
+
948
+ LOOP_N=$((LOOP_N + 1))
949
+
950
+ # Keep retrying the ssh-ready handshake until it is acknowledged so a flaky
951
+ # first POST never strands the controller.
952
+ if [ ! -f "$READY_FLAG" ]; then
953
+ if post_status "ssh-ready" "\"detail\":\"retry from lifecycle loop\",\"installer\":\"${INSTALLER}\""; then
954
+ touch "$READY_FLAG"
955
+ log "[loop] ssh-ready handshake posted (retry)"
956
+ fi
957
+ fi
958
+
959
+ # Periodic heartbeat so the controller log shows the runtime is alive while
960
+ # it waits for a trigger.
961
+ if [ "$((LOOP_N % 4))" -eq 0 ]; then
962
+ post_status "heartbeat" "\"detail\":\"awaiting install trigger\",\"uptimeSec\":$(( $(date +%s) - START_TS ))" >/dev/null 2>&1 || true
963
+ fi
964
+
965
+ if ! pidof sshd >/dev/null 2>&1; then
966
+ log "[loop] sshd not running, restarting..."
967
+ /usr/sbin/sshd 2>/dev/null || sshd 2>/dev/null
968
+ fi
969
+
970
+ if [ -f "$TRIGGER_FILE" ] && [ ! -f "$INSTALL_DONE" ]; then
971
+ log "[loop] install trigger detected"
972
+ console_log "ssh install trigger detected"
973
+ rm -f "$TRIGGER_FILE"
974
+ launch_installer
975
+ fi
976
+
977
+ if [ "$AUTO_INSTALL" = "1" ] && [ ! -f "$LAUNCHED_FLAG" ] && [ ! -f "$INSTALL_DONE" ]; then
978
+ NOW=$(date +%s)
979
+ if [ "$((NOW - START_TS))" -ge "$AUTO_INSTALL_FALLBACK_SECONDS" ]; then
980
+ log "[loop] AUTO_INSTALL fallback timeout reached; self-triggering installer"
981
+ launch_installer
982
+ fi
983
+ fi
984
+
985
+ sleep 15
986
+ done