openship 0.4.5 → 0.4.7

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 (314) hide show
  1. package/README.md +2 -24
  2. package/dist/bare-2HYDXQEH.js +23 -0
  3. package/dist/{bowser-L6PVH37V.js → bowser-O3AEA6AN.js} +3 -1
  4. package/dist/{chunk-YFLQGDN2.js → chunk-4TJC4JZQ.js} +18 -9
  5. package/dist/{chunk-JXQCFTDV.js → chunk-4Z5QO7N6.js} +4 -2
  6. package/dist/{chunk-JJVSOE4I.js → chunk-5MZ624VX.js} +2 -0
  7. package/dist/{chunk-TDFK6ISF.js → chunk-6APIPIJY.js} +6 -4
  8. package/dist/{chunk-3LCRNQ2C.js → chunk-6APULWSU.js} +151 -133
  9. package/dist/{chunk-FTBXJ2VA.js → chunk-6B5YCFFV.js} +6 -4
  10. package/dist/{chunk-MDFYN2QH.js → chunk-AVIB7CT7.js} +3 -1
  11. package/dist/{chunk-W7KGHYLV.js → chunk-DYPH4HCI.js} +2 -0
  12. package/dist/{chunk-5WI7ZXOC.js → chunk-EI575GHN.js} +4 -2
  13. package/dist/{chunk-Z6EKX6CX.js → chunk-FPRHYBY2.js} +2 -0
  14. package/dist/{chunk-FZJX6XP7.js → chunk-FRNAR33O.js} +4 -2
  15. package/dist/{chunk-XRWV5ZNR.js → chunk-FXTBHTWY.js} +360 -42
  16. package/dist/chunk-ILFETZOM.js +131 -0
  17. package/dist/{chunk-E3ZPCNPU.js → chunk-IMBD5PZ5.js} +251 -105
  18. package/dist/{chunk-VJTXRCTT.js → chunk-IPYPMI3S.js} +10 -6
  19. package/dist/{chunk-PARRPUXN.js → chunk-IXCHURVK.js} +5 -3
  20. package/dist/{chunk-YJAS5RQX.js → chunk-JYGD5WSN.js} +2 -0
  21. package/dist/{chunk-JWBXYO24.js → chunk-KI2EY3WB.js} +2 -0
  22. package/dist/{chunk-YVXF6GGR.js → chunk-L2VOGB2X.js} +5 -104
  23. package/dist/{chunk-K5OH5U7N.js → chunk-MZ2WEHHY.js} +5 -3
  24. package/dist/{chunk-SJBR527P.js → chunk-O6ZZF52V.js} +3 -1
  25. package/dist/{chunk-VLPJLXXB.js → chunk-OWED2GRM.js} +3 -1
  26. package/dist/{chunk-C4FOQJ63.js → chunk-OXWDY22G.js} +4 -2
  27. package/dist/{chunk-NPVJYR7M.js → chunk-Q2CIRAOK.js} +2 -0
  28. package/dist/chunk-R5BHFFAV.js +282 -0
  29. package/dist/{chunk-JYAGTMSJ.js → chunk-RPHRPFEH.js} +2 -0
  30. package/dist/{chunk-R74UB4X4.js → chunk-SJIFLLX4.js} +397 -85
  31. package/dist/{chunk-HYL4QYZM.js → chunk-TGIINPVM.js} +13 -2
  32. package/dist/{chunk-SYCZE6FQ.js → chunk-TYVME3XD.js} +7 -1
  33. package/dist/{chunk-UMYQALBH.js → chunk-UXWAVM4C.js} +1788 -1484
  34. package/dist/{chunk-HDV4NSA3.js → chunk-V6AN6XLZ.js} +16 -6
  35. package/dist/{chunk-3YCMJRDZ.js → chunk-VDMQJHPI.js} +36 -15
  36. package/dist/{chunk-RZPDJC2J.js → chunk-VFINNTUL.js} +20 -1
  37. package/dist/{chunk-65KKUJBR.js → chunk-VWPEKOH6.js} +4 -2
  38. package/dist/{chunk-GHXGCANU.js → chunk-W73X43R7.js} +4 -2
  39. package/dist/{chunk-7EYFCKZX.js → chunk-XFCDYZUQ.js} +8 -6
  40. package/dist/cloud-2KXREXMO.js +30 -0
  41. package/dist/{cloud-7IGG45CF.js → cloud-7QYOGF7F.js} +4 -2
  42. package/dist/detect-2XSCFFTF.js +44 -0
  43. package/dist/{dist-NQB6QGX3.js → dist-IQJ6H6UZ.js} +4 -2
  44. package/dist/{dist-es-DCR6UJMP.js → dist-es-5DY7K32L.js} +7 -5
  45. package/dist/{dist-es-TYYZ5KEF.js → dist-es-JSTDUS7Q.js} +7 -5
  46. package/dist/{dist-es-7EZIM4JU.js → dist-es-OSNJBLXB.js} +6 -4
  47. package/dist/{dist-es-6RSPR56Q.js → dist-es-RYHIPOTN.js} +15 -13
  48. package/dist/{dist-es-33Z3Y6VE.js → dist-es-VNKHQVIB.js} +5 -3
  49. package/dist/{dist-es-D6QQVWRZ.js → dist-es-WV4AMOII.js} +9 -7
  50. package/dist/{dist-es-GMEQINIE.js → dist-es-X3B5QYKB.js} +7 -5
  51. package/dist/docker-LODK5Y2S.js +16 -0
  52. package/dist/docker-edge-executor-VHW3JPJS.js +13 -0
  53. package/dist/edge-import-ZQ4Y5HEA.js +45 -0
  54. package/dist/ensure-container-edge-ED25XL3Z.js +31 -0
  55. package/dist/{event-streams-G7F6Q7QY.js → event-streams-EHRAKL75.js} +5 -3
  56. package/dist/{executor-O5NR7LMP.js → executor-YPT6RH6O.js} +9 -7
  57. package/dist/index.d.ts +2 -1
  58. package/dist/index.js +279 -245
  59. package/dist/{loadSso-LH753OSJ.js → loadSso-46FQRIZS.js} +11 -9
  60. package/dist/local-executor-V7U5VOZW.js +12 -0
  61. package/dist/nginx-XWJAOGS4.js +24 -0
  62. package/dist/{noop-6KC6HRDB.js → noop-FMMFG2EZ.js} +4 -2
  63. package/dist/{openresty-lua-KFCOJAG4.js → openresty-lua-4WLGDSER.js} +11 -3
  64. package/dist/server/engine/ChangeLog +2289 -0
  65. package/dist/server/engine/Documentations +5 -0
  66. package/dist/server/engine/LICENSE +674 -0
  67. package/dist/server/engine/README.md +34 -0
  68. package/dist/server/engine/conf/amavisd +150 -0
  69. package/dist/server/engine/conf/clamav +71 -0
  70. package/dist/server/engine/conf/core +632 -0
  71. package/dist/server/engine/conf/dovecot +151 -0
  72. package/dist/server/engine/conf/fail2ban +72 -0
  73. package/dist/server/engine/conf/global +698 -0
  74. package/dist/server/engine/conf/iredapd +52 -0
  75. package/dist/server/engine/conf/logwatch +28 -0
  76. package/dist/server/engine/conf/postfix +97 -0
  77. package/dist/server/engine/conf/postgresql +93 -0
  78. package/dist/server/engine/conf/spamassassin +39 -0
  79. package/dist/server/engine/dialog/config_via_dialog.sh +258 -0
  80. package/dist/server/engine/dialog/optional_components.sh +122 -0
  81. package/dist/server/engine/dialog/pgsql_config.sh +52 -0
  82. package/dist/server/engine/dialog/virtual_domain_config.sh +94 -0
  83. package/dist/server/engine/functions/amavisd.sh +267 -0
  84. package/dist/server/engine/functions/backend.sh +85 -0
  85. package/dist/server/engine/functions/clamav.sh +100 -0
  86. package/dist/server/engine/functions/cleanup.sh +393 -0
  87. package/dist/server/engine/functions/dovecot.sh +583 -0
  88. package/dist/server/engine/functions/fail2ban.sh +209 -0
  89. package/dist/server/engine/functions/iredapd.sh +356 -0
  90. package/dist/server/engine/functions/optional_components.sh +24 -0
  91. package/dist/server/engine/functions/packages.sh +522 -0
  92. package/dist/server/engine/functions/packages_freebsd.sh +179 -0
  93. package/dist/server/engine/functions/postfix.sh +457 -0
  94. package/dist/server/engine/functions/postgresql.sh +239 -0
  95. package/dist/server/engine/functions/spamassassin.sh +49 -0
  96. package/dist/server/engine/functions/system_accounts.sh +128 -0
  97. package/dist/server/engine/iRedMail.sh +144 -0
  98. package/dist/server/engine/pkgs/get_all.sh +338 -0
  99. package/dist/server/engine/pkgs/pkgs.freebsd.sha256 +3 -0
  100. package/dist/server/engine/pkgs/pkgs.openbsd.sha256 +6 -0
  101. package/dist/server/engine/pkgs/pkgs.sha256 +1 -0
  102. package/dist/server/engine/samples/amavisd/amavisd.conf +677 -0
  103. package/dist/server/engine/samples/amavisd/amavisd.mysql +278 -0
  104. package/dist/server/engine/samples/amavisd/amavisd.pgsql +253 -0
  105. package/dist/server/engine/samples/amavisd/amavisd.schema +942 -0
  106. package/dist/server/engine/samples/amavisd/default_spam_policy.sql +46 -0
  107. package/dist/server/engine/samples/dovecot/dovecot-2.4-mariadb.conf +758 -0
  108. package/dist/server/engine/samples/dovecot/dovecot-2.4-openldap.conf +767 -0
  109. package/dist/server/engine/samples/dovecot/dovecot-2.4-pgsql.conf +762 -0
  110. package/dist/server/engine/samples/dovecot/dovecot-last-login.conf +50 -0
  111. package/dist/server/engine/samples/dovecot/dovecot-ldap.conf +21 -0
  112. package/dist/server/engine/samples/dovecot/dovecot-share-folder.conf +22 -0
  113. package/dist/server/engine/samples/dovecot/dovecot-sql.conf +28 -0
  114. package/dist/server/engine/samples/dovecot/dovecot-used-quota.conf +13 -0
  115. package/dist/server/engine/samples/dovecot/dovecot.conf +484 -0
  116. package/dist/server/engine/samples/dovecot/dovecot.sieve +7 -0
  117. package/dist/server/engine/samples/dovecot/dovecot2-quota-warning.sh +38 -0
  118. package/dist/server/engine/samples/dovecot/sql/imap_share_folder.mysql +16 -0
  119. package/dist/server/engine/samples/dovecot/sql/last_login.mysql +12 -0
  120. package/dist/server/engine/samples/dovecot/sql/used_quota.mysql +26 -0
  121. package/dist/server/engine/samples/dovecot/systemd/override.conf +3 -0
  122. package/dist/server/engine/samples/fail2ban/action.d/banned_db.conf +9 -0
  123. package/dist/server/engine/samples/fail2ban/bin/fail2ban_banned_db +268 -0
  124. package/dist/server/engine/samples/fail2ban/fail2ban.local +17 -0
  125. package/dist/server/engine/samples/fail2ban/filter.d/dovecot.iredmail.conf +5 -0
  126. package/dist/server/engine/samples/fail2ban/filter.d/postfix-pregreet.iredmail.conf +16 -0
  127. package/dist/server/engine/samples/fail2ban/filter.d/postfix.iredmail.conf +18 -0
  128. package/dist/server/engine/samples/fail2ban/filter.d/roundcube.iredmail.conf +9 -0
  129. package/dist/server/engine/samples/fail2ban/jail.d/dovecot.local +8 -0
  130. package/dist/server/engine/samples/fail2ban/jail.d/nginx-http-auth.local +8 -0
  131. package/dist/server/engine/samples/fail2ban/jail.d/postfix-pregreet.local +9 -0
  132. package/dist/server/engine/samples/fail2ban/jail.d/postfix.local +8 -0
  133. package/dist/server/engine/samples/fail2ban/jail.d/roundcube.local +9 -0
  134. package/dist/server/engine/samples/fail2ban/jail.d/sogo.local +8 -0
  135. package/dist/server/engine/samples/fail2ban/jail.d/sshd.local +8 -0
  136. package/dist/server/engine/samples/fail2ban/jail.local +6 -0
  137. package/dist/server/engine/samples/fail2ban/openbsd/rc +27 -0
  138. package/dist/server/engine/samples/fail2ban/sql/fail2ban.mysql +49 -0
  139. package/dist/server/engine/samples/fail2ban/sql/fail2ban.pgsql +48 -0
  140. package/dist/server/engine/samples/firewall/firewalld/services/ssh.xml +6 -0
  141. package/dist/server/engine/samples/firewall/firewalld/zones/iredmail.xml +15 -0
  142. package/dist/server/engine/samples/firewall/iptables/ip6tables.init.debian +362 -0
  143. package/dist/server/engine/samples/firewall/iptables/ip6tables.rules +53 -0
  144. package/dist/server/engine/samples/firewall/iptables/iptables.init.debian +363 -0
  145. package/dist/server/engine/samples/firewall/iptables/iptables.rules +54 -0
  146. package/dist/server/engine/samples/firewall/nftables.conf +58 -0
  147. package/dist/server/engine/samples/freebsd/newsyslog.conf.d/dovecot.conf +3 -0
  148. package/dist/server/engine/samples/freebsd/newsyslog.conf.d/iredapd.conf +1 -0
  149. package/dist/server/engine/samples/freebsd/newsyslog.conf.d/mlmmjadmin.conf +1 -0
  150. package/dist/server/engine/samples/freebsd/newsyslog.conf.d/php-fpm.conf +2 -0
  151. package/dist/server/engine/samples/freebsd/newsyslog.conf.d/slapd.conf +1 -0
  152. package/dist/server/engine/samples/freebsd/syslog.d/dovecot.conf +2 -0
  153. package/dist/server/engine/samples/freebsd/syslog.d/fail2ban.conf +2 -0
  154. package/dist/server/engine/samples/freebsd/syslog.d/iredapd.conf +2 -0
  155. package/dist/server/engine/samples/freebsd/syslog.d/mlmmjadmin.conf +2 -0
  156. package/dist/server/engine/samples/freebsd/syslog.d/php-fpm.conf +2 -0
  157. package/dist/server/engine/samples/freebsd/syslog.d/slapd.conf +2 -0
  158. package/dist/server/engine/samples/iredmail/iredmail.mysql +491 -0
  159. package/dist/server/engine/samples/iredmail/iredmail.pgsql +465 -0
  160. package/dist/server/engine/samples/iredmail/iredmail.schema +456 -0
  161. package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.3.pgsql +40 -0
  162. package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.4.pgsql +18 -0
  163. package/dist/server/engine/samples/logrotate/dovecot +13 -0
  164. package/dist/server/engine/samples/logrotate/iredapd +13 -0
  165. package/dist/server/engine/samples/logrotate/mlmmjadmin +13 -0
  166. package/dist/server/engine/samples/logrotate/openldap +19 -0
  167. package/dist/server/engine/samples/logrotate/php-fpm +13 -0
  168. package/dist/server/engine/samples/openbsd/ldapd.conf +58 -0
  169. package/dist/server/engine/samples/openbsd/pf.conf +28 -0
  170. package/dist/server/engine/samples/postfix/command_filter.pcre +3 -0
  171. package/dist/server/engine/samples/postfix/freebsd/mailer.conf +9 -0
  172. package/dist/server/engine/samples/postfix/helo_access.pcre +180 -0
  173. package/dist/server/engine/samples/postfix/ldap/catchall_maps.cf +11 -0
  174. package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_domain.cf +11 -0
  175. package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_user.cf +11 -0
  176. package/dist/server/engine/samples/postfix/ldap/relay_domains.cf +11 -0
  177. package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_domain.cf +11 -0
  178. package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_user.cf +11 -0
  179. package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_domain.cf +11 -0
  180. package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_user.cf +11 -0
  181. package/dist/server/engine/samples/postfix/ldap/sender_login_maps.cf +11 -0
  182. package/dist/server/engine/samples/postfix/ldap/transport_maps_domain.cf +11 -0
  183. package/dist/server/engine/samples/postfix/ldap/transport_maps_user.cf +11 -0
  184. package/dist/server/engine/samples/postfix/ldap/virtual_alias_maps.cf +11 -0
  185. package/dist/server/engine/samples/postfix/ldap/virtual_group_maps.cf +11 -0
  186. package/dist/server/engine/samples/postfix/ldap/virtual_group_members_maps.cf +11 -0
  187. package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_domains.cf +11 -0
  188. package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_maps.cf +12 -0
  189. package/dist/server/engine/samples/postfix/main.cf +282 -0
  190. package/dist/server/engine/samples/postfix/main.cf.amavisd +7 -0
  191. package/dist/server/engine/samples/postfix/main.cf.dovecot +8 -0
  192. package/dist/server/engine/samples/postfix/main.cf.ldap +39 -0
  193. package/dist/server/engine/samples/postfix/main.cf.mlmmj +5 -0
  194. package/dist/server/engine/samples/postfix/main.cf.mysql +39 -0
  195. package/dist/server/engine/samples/postfix/main.cf.pgsql +39 -0
  196. package/dist/server/engine/samples/postfix/main.cf.postscreen +30 -0
  197. package/dist/server/engine/samples/postfix/master.cf +87 -0
  198. package/dist/server/engine/samples/postfix/mysql/catchall_maps.cf +5 -0
  199. package/dist/server/engine/samples/postfix/mysql/domain_alias_catchall_maps.cf +5 -0
  200. package/dist/server/engine/samples/postfix/mysql/domain_alias_maps.cf +5 -0
  201. package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_domain.cf +5 -0
  202. package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_user.cf +5 -0
  203. package/dist/server/engine/samples/postfix/mysql/relay_domains.cf +5 -0
  204. package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_domain.cf +5 -0
  205. package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_user.cf +5 -0
  206. package/dist/server/engine/samples/postfix/mysql/sender_dependent_relayhost_maps.cf +6 -0
  207. package/dist/server/engine/samples/postfix/mysql/sender_login_maps.cf +5 -0
  208. package/dist/server/engine/samples/postfix/mysql/transport_maps_domain.cf +5 -0
  209. package/dist/server/engine/samples/postfix/mysql/transport_maps_maillist.cf +5 -0
  210. package/dist/server/engine/samples/postfix/mysql/transport_maps_user.cf +5 -0
  211. package/dist/server/engine/samples/postfix/mysql/virtual_alias_maps.cf +5 -0
  212. package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_domains.cf +5 -0
  213. package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_maps.cf +5 -0
  214. package/dist/server/engine/samples/postfix/pgsql/catchall_maps.cf +5 -0
  215. package/dist/server/engine/samples/postfix/pgsql/domain_alias_catchall_maps.cf +5 -0
  216. package/dist/server/engine/samples/postfix/pgsql/domain_alias_maps.cf +5 -0
  217. package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_domain.cf +5 -0
  218. package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_user.cf +5 -0
  219. package/dist/server/engine/samples/postfix/pgsql/relay_domains.cf +5 -0
  220. package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_domain.cf +5 -0
  221. package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_user.cf +5 -0
  222. package/dist/server/engine/samples/postfix/pgsql/sender_dependent_relayhost_maps.cf +6 -0
  223. package/dist/server/engine/samples/postfix/pgsql/sender_login_maps.cf +5 -0
  224. package/dist/server/engine/samples/postfix/pgsql/transport_maps_domain.cf +5 -0
  225. package/dist/server/engine/samples/postfix/pgsql/transport_maps_maillist.cf +5 -0
  226. package/dist/server/engine/samples/postfix/pgsql/transport_maps_user.cf +5 -0
  227. package/dist/server/engine/samples/postfix/pgsql/virtual_alias_maps.cf +5 -0
  228. package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_domains.cf +5 -0
  229. package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_maps.cf +5 -0
  230. package/dist/server/engine/samples/postfix/postscreen_access.cidr +6 -0
  231. package/dist/server/engine/samples/postgresql/sql/add_first_domain_and_user.sql +34 -0
  232. package/dist/server/engine/samples/postgresql/sql/grant_permissions.sql +14 -0
  233. package/dist/server/engine/samples/postgresql/sql/init_vmail_db.sql +15 -0
  234. package/dist/server/engine/samples/rsyslog.d/1-iredmail-dovecot.conf +23 -0
  235. package/dist/server/engine/samples/rsyslog.d/1-iredmail-fail2ban.conf +2 -0
  236. package/dist/server/engine/samples/rsyslog.d/1-iredmail-iredapd.conf +12 -0
  237. package/dist/server/engine/samples/rsyslog.d/1-iredmail-mlmmjadmin.conf +12 -0
  238. package/dist/server/engine/samples/rsyslog.d/1-iredmail-openldap.conf +2 -0
  239. package/dist/server/engine/samples/rsyslog.d/1-iredmail-phpfpm.conf +3 -0
  240. package/dist/server/engine/samples/spamassassin/local.cf +186 -0
  241. package/dist/server/engine/samples/spamassassin/razor.conf +1 -0
  242. package/dist/server/engine/samples/systemd/clamd.service.d/override.conf +2 -0
  243. package/dist/server/engine/samples/systemd/mariadb.service.d/override.conf +3 -0
  244. package/dist/server/engine/samples/systemd/slapd.service.d/override.conf +6 -0
  245. package/dist/server/engine/samples/yum/CentOS-Linux-AppStream.repo +6 -0
  246. package/dist/server/engine/samples/yum/CentOS-Linux-PowerTools.repo +6 -0
  247. package/dist/server/engine/samples/yum/CentOS-Stream-AppStream.repo +7 -0
  248. package/dist/server/engine/samples/yum/CentOS-Stream-PowerTools.repo +7 -0
  249. package/dist/server/engine/samples/yum/symas-openldap.repo +6 -0
  250. package/dist/server/engine/tools/add_enabled_service.py +60 -0
  251. package/dist/server/engine/tools/backup_mysql.sh +238 -0
  252. package/dist/server/engine/tools/backup_openldap.sh +230 -0
  253. package/dist/server/engine/tools/backup_pgsql.sh +217 -0
  254. package/dist/server/engine/tools/backup_sogo.sh +156 -0
  255. package/dist/server/engine/tools/create_mail_user_OpenLDAP.py +335 -0
  256. package/dist/server/engine/tools/create_mail_user_OpenLDAP.sh +287 -0
  257. package/dist/server/engine/tools/create_mail_user_SQL.sh +127 -0
  258. package/dist/server/engine/tools/enable_postscreen.sh +144 -0
  259. package/dist/server/engine/tools/fail2ban_unban_ip.sh +39 -0
  260. package/dist/server/engine/tools/find_sasl_login_ip.sh +20 -0
  261. package/dist/server/engine/tools/find_top_sasl_usernames.sh +28 -0
  262. package/dist/server/engine/tools/generate_ssl_keys.sh +85 -0
  263. package/dist/server/engine/tools/kill_high_cpu_sogo_process.sh +32 -0
  264. package/dist/server/engine/tools/ldap_assign_user_to_groups.py +151 -0
  265. package/dist/server/engine/tools/ldap_move_members_to_another_group.py +129 -0
  266. package/dist/server/engine/tools/migrate_sql_alias_table.py +177 -0
  267. package/dist/server/engine/update/0.9.8/amavisd.mysql +29 -0
  268. package/dist/server/engine/update/0.9.8/amavisd.pgsql +39 -0
  269. package/dist/server/engine/update/0.9.8/iredmail.mysql +53 -0
  270. package/dist/server/engine/update/0.9.8/iredmail.pgsql +61 -0
  271. package/dist/server/engine/update/0.9.9/iredmail.mysql +2 -0
  272. package/dist/server/engine/update/0.9.9/iredmail.pgsql +2 -0
  273. package/dist/server/engine/update/1.0/iredmail.mysql +2 -0
  274. package/dist/server/engine/update/1.0/iredmail.pgsql +2 -0
  275. package/dist/server/engine/update/1.2/last_login.mysql +16 -0
  276. package/dist/server/engine/update/1.4.0/iredmail.mysql +22 -0
  277. package/dist/server/engine/update/1.4.0/iredmail.pgsql +20 -0
  278. package/dist/server/engine/update/1.4.1/iredmail.mysql +3 -0
  279. package/dist/server/engine/update/1.4.1/iredmail.pgsql +3 -0
  280. package/dist/server/engine/update/1.4.1/sogo.mysql +11 -0
  281. package/dist/server/engine/update/1.4.1/sogo.pgsql +30 -0
  282. package/dist/server/engine/update/1.4.1/update-ldap.py +66 -0
  283. package/dist/server/engine/update/1.4.2/iredmail.mysql +9 -0
  284. package/dist/server/engine/update/1.4.2/iredmail.pgsql +9 -0
  285. package/dist/server/engine/update/1.4.2/sogo.pgsql +30 -0
  286. package/dist/server/engine/update/1.6.0/sogo_view.pgsql +27 -0
  287. package/dist/server/engine/update/1.6.3/iredmail.mysql +1 -0
  288. package/dist/server/engine/update/1.7.0/fail2ban.mysql +11 -0
  289. package/dist/server/engine/update/1.7.0/fail2ban.pgsql +12 -0
  290. package/dist/server/engine/update/1.7.1/amavisd.mysql +1 -0
  291. package/dist/server/engine/update/1.7.2/vmail.mysql +30 -0
  292. package/dist/server/engine/update/1.7.3/deleted_mailboxes.mysql +43 -0
  293. package/dist/server/engine/update/1.7.3/iredadmin.mysql +26 -0
  294. package/dist/server/engine/update/1.7.3/vmail.mysql +79 -0
  295. package/dist/server/engine/update/1.7.3/vmail.pgsql +9 -0
  296. package/dist/server/engine/update/README.md +1 -0
  297. package/dist/server/engine/update/ldap/README.md +40 -0
  298. package/dist/server/engine/update/ldap/update-ldap-dovecot-2.3.py +69 -0
  299. package/dist/server/index.js +55793 -53701
  300. package/dist/server/migrations/0071_gh_device_token.sql +3 -0
  301. package/dist/server/migrations/0072_gh_device_token_method.sql +1 -0
  302. package/dist/server/migrations/meta/_journal.json +14 -0
  303. package/dist/setup-2DMFIA74.js +20 -0
  304. package/dist/{signin-PVC7MBZJ.js → signin-ITOPKKUB.js} +11 -9
  305. package/dist/{sso-oidc-ZXY77BSL.js → sso-oidc-NON2PD7Y.js} +11 -9
  306. package/dist/{sts-LX5L4UU3.js → sts-HHFFSAY2.js} +10 -8
  307. package/package.json +1 -1
  308. package/dist/bare-CNSFDNSZ.js +0 -20
  309. package/dist/cloud-655YYCEW.js +0 -26
  310. package/dist/docker-UWQPDEGW.js +0 -14
  311. package/dist/docker-edge-executor-ZLAYE5FE.js +0 -11
  312. package/dist/edge-import-AFID2EN3.js +0 -41
  313. package/dist/nginx-M36GDYL7.js +0 -18
  314. package/dist/setup-ZXXB5S22.js +0 -16
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env sh
2
+ ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
1
3
  import { createRequire as __ospCreateRequire } from "node:module";
2
4
  const require = __ospCreateRequire(import.meta.url);
3
5
  import {
@@ -5,8 +7,9 @@ import {
5
7
  generateDockerfile,
6
8
  prepareSourceTree,
7
9
  resolveDockerfileCandidates,
8
- resolveServiceDockerfile
9
- } from "./chunk-HDV4NSA3.js";
10
+ resolveServiceDockerfile,
11
+ staticBuilderOutputPath
12
+ } from "./chunk-V6AN6XLZ.js";
10
13
  import {
11
14
  BuildLogger,
12
15
  assembleGitClone,
@@ -15,20 +18,20 @@ import {
15
18
  shellGitSshWriter,
16
19
  sq,
17
20
  transferLocalDirectory
18
- } from "./chunk-JXQCFTDV.js";
21
+ } from "./chunk-4Z5QO7N6.js";
19
22
  import {
20
23
  connectSshClient,
21
24
  execSshCommand,
22
25
  openSshExecChannel,
23
26
  openSshUnixSocket
24
- } from "./chunk-C4FOQJ63.js";
27
+ } from "./chunk-OXWDY22G.js";
25
28
  import {
26
29
  isRuntimeNotFoundError
27
- } from "./chunk-JYAGTMSJ.js";
30
+ } from "./chunk-RPHRPFEH.js";
28
31
  import {
29
32
  safeErrorMessage,
30
33
  withTimeout
31
- } from "./chunk-3LCRNQ2C.js";
34
+ } from "./chunk-6APULWSU.js";
32
35
 
33
36
  // ../../packages/adapters/src/runtime/docker.ts
34
37
  import Dockerode from "dockerode";
@@ -79,12 +82,133 @@ function scopeVolumeBinds(slug, rawVolumes, enabled) {
79
82
  });
80
83
  }
81
84
 
82
- // ../../packages/adapters/src/runtime/docker-ssh-agent.ts
85
+ // ../../packages/adapters/src/runtime/docker-exec-stream.ts
83
86
  import net from "net";
87
+ import tls from "tls";
88
+ import { Duplex } from "stream";
89
+ var HEADER_END = "\r\n\r\n";
90
+ var UPGRADE_TIMEOUT_MS = 2e4;
91
+ function connect(conn) {
92
+ if (conn.socketPath) return net.connect({ path: conn.socketPath });
93
+ const port = Number(conn.port ?? (conn.protocol === "https" ? 443 : 80));
94
+ const host = conn.host ?? "127.0.0.1";
95
+ if (conn.protocol === "https") {
96
+ return tls.connect({ host, port, ca: conn.ca, cert: conn.cert, key: conn.key });
97
+ }
98
+ return net.connect({ port, host });
99
+ }
100
+ function bridgeSocket(socket, leftover) {
101
+ const out = new Duplex({
102
+ read() {
103
+ socket.resume();
104
+ },
105
+ write(chunk, _enc, cb) {
106
+ socket.write(chunk, (err) => cb(err ?? null));
107
+ },
108
+ final(cb) {
109
+ if (!socket.destroyed) socket.end();
110
+ cb();
111
+ },
112
+ destroy(err, cb) {
113
+ socket.destroy(err ?? void 0);
114
+ cb(err);
115
+ }
116
+ });
117
+ let readEnded = false;
118
+ const endRead = () => {
119
+ if (readEnded) return;
120
+ readEnded = true;
121
+ out.push(null);
122
+ };
123
+ if (leftover.length > 0) out.push(leftover);
124
+ socket.on("data", (chunk) => {
125
+ if (!out.push(chunk)) socket.pause();
126
+ });
127
+ socket.on("end", endRead);
128
+ socket.on("error", (err) => out.destroy(err));
129
+ socket.on("close", () => {
130
+ endRead();
131
+ if (!out.writableEnded) out.end();
132
+ });
133
+ return out;
134
+ }
135
+ function startExecStream(conn, execId, opts) {
136
+ return new Promise((resolve, reject) => {
137
+ const socket = connect(conn);
138
+ let settled = false;
139
+ let head = Buffer.alloc(0);
140
+ const fail = (err) => {
141
+ if (settled) return;
142
+ settled = true;
143
+ clearTimeout(timer);
144
+ socket.destroy();
145
+ reject(err);
146
+ };
147
+ const timer = setTimeout(
148
+ () => fail(new Error(`docker exec upgrade timed out after ${UPGRADE_TIMEOUT_MS}ms`)),
149
+ UPGRADE_TIMEOUT_MS
150
+ );
151
+ const onData = (chunk) => {
152
+ if (settled) return;
153
+ head = head.length === 0 ? Buffer.from(chunk) : Buffer.concat([head, chunk]);
154
+ const text = head.toString("latin1");
155
+ const end = text.indexOf(HEADER_END);
156
+ if (end === -1) {
157
+ if (head.length > 64 * 1024) fail(new Error("docker exec upgrade: response head too large"));
158
+ return;
159
+ }
160
+ const statusLine = text.slice(0, text.indexOf("\r\n"));
161
+ if (!/ 101 /.test(statusLine)) {
162
+ const body2 = text.slice(end + HEADER_END.length).trim();
163
+ fail(new Error(`docker exec start failed: ${statusLine}${body2 ? ` \u2014 ${body2}` : ""}`));
164
+ return;
165
+ }
166
+ settled = true;
167
+ clearTimeout(timer);
168
+ socket.removeListener("data", onData);
169
+ socket.removeListener("error", fail);
170
+ socket.removeListener("close", onEarlyClose);
171
+ const headBytes = Buffer.byteLength(text.slice(0, end + HEADER_END.length), "latin1");
172
+ resolve(bridgeSocket(socket, head.subarray(headBytes)));
173
+ };
174
+ const onEarlyClose = () => fail(new Error("docker exec start: connection closed before upgrade"));
175
+ socket.on("data", onData);
176
+ socket.on("error", fail);
177
+ socket.on("close", onEarlyClose);
178
+ const body = JSON.stringify({ Detach: false, Tty: opts.tty });
179
+ socket.write(
180
+ `POST /exec/${execId}/start HTTP/1.1\r
181
+ Host: ${conn.socketPath ? "localhost" : conn.host ?? "localhost"}\r
182
+ Content-Type: application/json\r
183
+ Content-Length: ${Buffer.byteLength(body)}\r
184
+ Connection: Upgrade\r
185
+ Upgrade: tcp\r
186
+ \r
187
+ ` + body
188
+ );
189
+ });
190
+ }
191
+ function daemonConnectionFrom(docker) {
192
+ const m = docker.modem ?? {};
193
+ return {
194
+ socketPath: typeof m.socketPath === "string" ? m.socketPath : void 0,
195
+ host: typeof m.host === "string" ? m.host : void 0,
196
+ port: typeof m.port === "number" || typeof m.port === "string" ? m.port : void 0,
197
+ protocol: typeof m.protocol === "string" ? m.protocol : void 0,
198
+ ca: m.ca,
199
+ cert: m.cert,
200
+ key: m.key
201
+ };
202
+ }
203
+
204
+ // ../../packages/adapters/src/runtime/docker-ssh-agent.ts
205
+ import net2 from "net";
84
206
  var DEFAULT_REMOTE_DOCKER_SOCKET_PATH = "/var/run/docker.sock";
85
207
  var resolvedDockerSocketPathCache = /* @__PURE__ */ new WeakMap();
86
208
  var DOCKER_DIAL_STDIO_COMMAND = "docker system dial-stdio";
87
209
  var STREAMLOCAL_PROBE_TIMEOUT_MS = 8e3;
210
+ var STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS = 3e3;
211
+ var VERIFY_BUFFER_CAP_BYTES = 8 * 1024 * 1024;
88
212
  function toSshConfig(opts) {
89
213
  return {
90
214
  host: opts.host ?? "",
@@ -182,13 +306,107 @@ async function openStreamlocalUpstream(opts) {
182
306
  throw error;
183
307
  }
184
308
  }
309
+ function pipeThrough(client, upstream) {
310
+ const teardown = () => {
311
+ client.destroy();
312
+ upstream.destroy();
313
+ };
314
+ client.on("error", teardown);
315
+ upstream.on("error", teardown);
316
+ client.once("close", () => upstream.destroy());
317
+ upstream.once("close", () => client.destroy());
318
+ client.pipe(upstream);
319
+ upstream.pipe(client);
320
+ }
321
+ function awaitFirstByte(upstream, ms) {
322
+ return new Promise((resolve) => {
323
+ const finish = (chunk) => {
324
+ clearTimeout(timer);
325
+ upstream.removeListener("data", onData);
326
+ upstream.removeListener("error", onFail);
327
+ upstream.removeListener("close", onFail);
328
+ resolve(chunk);
329
+ };
330
+ const onData = (chunk) => finish(chunk);
331
+ const onFail = () => finish(null);
332
+ const timer = setTimeout(() => finish(null), ms);
333
+ upstream.on("data", onData);
334
+ upstream.once("error", onFail);
335
+ upstream.once("close", onFail);
336
+ });
337
+ }
338
+ function captureClient(client) {
339
+ const chunks = [];
340
+ let bytes = 0;
341
+ let overflowed = false;
342
+ let closed = false;
343
+ let live = null;
344
+ const onData = (chunk) => {
345
+ if (live) live.write(chunk);
346
+ if (overflowed) return;
347
+ chunks.push(chunk);
348
+ bytes += chunk.length;
349
+ if (bytes >= VERIFY_BUFFER_CAP_BYTES) {
350
+ overflowed = true;
351
+ client.pause();
352
+ }
353
+ };
354
+ const onGone = () => {
355
+ closed = true;
356
+ };
357
+ client.on("data", onData);
358
+ client.once("error", onGone);
359
+ client.once("close", onGone);
360
+ const detach = () => {
361
+ client.removeListener("data", onData);
362
+ client.removeListener("error", onGone);
363
+ client.removeListener("close", onGone);
364
+ };
365
+ return {
366
+ get closed() {
367
+ return closed;
368
+ },
369
+ get overflowed() {
370
+ return overflowed;
371
+ },
372
+ /** Replay everything buffered so far onto `upstream` and forward the rest
373
+ * live. Safe to call again on a different upstream (the fallback): the full
374
+ * buffer is retained until `commit`, so the replay is complete each time. */
375
+ feed(upstream) {
376
+ for (const chunk of chunks) upstream.write(chunk);
377
+ live = upstream;
378
+ },
379
+ /** Stop forwarding to the current upstream (keep buffering) — used before
380
+ * destroying a dead channel so late bytes never hit a torn-down stream. */
381
+ stop() {
382
+ live = null;
383
+ },
384
+ /** Terminal: detach and hand the socket to the (already-fed) `upstream` via a
385
+ * bidi pipe, or destroy it if the client already went away. */
386
+ commit(upstream) {
387
+ detach();
388
+ chunks.length = 0;
389
+ if (closed) {
390
+ upstream.destroy();
391
+ return;
392
+ }
393
+ pipeThrough(client, upstream);
394
+ },
395
+ /** Terminal: no usable upstream — surface the error to dockerode. */
396
+ fail(err) {
397
+ detach();
398
+ client.destroy(err instanceof Error ? err : new Error(String(err)));
399
+ }
400
+ };
401
+ }
185
402
  function createDockerSshBridge(opts) {
186
403
  const clients = /* @__PURE__ */ new Set();
187
404
  let upstreamMode = null;
188
405
  let modeDecision = null;
189
406
  let dialClient = null;
190
- const openDialStdioUpstream = async () => {
191
- if (opts.executor?.openDockerDialStdio) {
407
+ let pooledUnreliable = false;
408
+ const openDialStdioUpstream = async (forceEphemeral = false) => {
409
+ if (!forceEphemeral && opts.executor?.openDockerDialStdio) {
192
410
  const stream = await opts.executor.openDockerDialStdio();
193
411
  stream.once(
194
412
  "error",
@@ -251,29 +469,57 @@ function createDockerSshBridge(opts) {
251
469
  modeDecision ??= decideMode().then((mode) => upstreamMode = mode);
252
470
  return modeDecision;
253
471
  };
254
- const openUpstream = async () => {
255
- const mode = await ensureMode();
256
- return mode === "dialstdio" ? openDialStdioUpstream() : openStreamlocalUpstream(opts);
472
+ const downgradeToDialStdio = async (capture, reason) => {
473
+ console.warn(
474
+ `[docker-ssh] streamlocal unusable (${opts.host ?? "?"}): ${reason} \u2014 downgrading this bridge to dial-stdio (fresh connection) and replaying the buffered request.`
475
+ );
476
+ upstreamMode = "dialstdio";
477
+ pooledUnreliable = true;
478
+ const upstream = await openDialStdioUpstream(true);
479
+ capture.feed(upstream);
480
+ capture.commit(upstream);
481
+ };
482
+ const bridgeClient = async (client) => {
483
+ const capture = captureClient(client);
484
+ try {
485
+ const mode = await ensureMode();
486
+ if (mode === "dialstdio") {
487
+ const upstream = await openDialStdioUpstream(pooledUnreliable);
488
+ capture.feed(upstream);
489
+ capture.commit(upstream);
490
+ return;
491
+ }
492
+ let channel;
493
+ try {
494
+ channel = await withTimeout(
495
+ openStreamlocalUpstream(opts),
496
+ STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS,
497
+ `channel open timed out after ${STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS / 1e3}s`
498
+ );
499
+ } catch (err) {
500
+ await downgradeToDialStdio(capture, safeErrorMessage(err));
501
+ return;
502
+ }
503
+ capture.feed(channel);
504
+ const firstByte = capture.overflowed ? null : await awaitFirstByte(channel, STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS);
505
+ if (capture.overflowed || firstByte) {
506
+ if (firstByte) client.write(firstByte);
507
+ capture.commit(channel);
508
+ return;
509
+ }
510
+ capture.stop();
511
+ channel.destroy();
512
+ await downgradeToDialStdio(capture, "channel opened but no data flowed");
513
+ } catch (err) {
514
+ console.warn(`[docker-ssh] bridge client failed (${opts.host ?? "?"}): ${safeErrorMessage(err)}`);
515
+ capture.fail(err);
516
+ }
257
517
  };
258
- const server = net.createServer((client) => {
518
+ const server = net2.createServer((client) => {
259
519
  clients.add(client);
260
520
  client.setNoDelay(true);
261
521
  client.once("close", () => clients.delete(client));
262
- openUpstream().then((upstream) => {
263
- const teardown = () => {
264
- client.destroy();
265
- upstream.destroy();
266
- };
267
- client.on("error", teardown);
268
- upstream.on("error", teardown);
269
- client.once("close", () => upstream.destroy());
270
- upstream.once("close", () => client.destroy());
271
- client.pipe(upstream);
272
- upstream.pipe(client);
273
- }).catch((error) => {
274
- console.warn(`[docker-ssh] bridge upstream open failed: ${safeErrorMessage(error)}`);
275
- client.destroy(error instanceof Error ? error : new Error(String(error)));
276
- });
522
+ void bridgeClient(client);
277
523
  });
278
524
  return {
279
525
  start: () => new Promise((resolve, reject) => {
@@ -557,16 +803,16 @@ function parseTimestampedLine(line) {
557
803
  };
558
804
  }
559
805
  function firstNetworkIp(networks) {
560
- for (const net2 of Object.values(networks ?? {})) {
561
- if (net2?.IPAddress) return net2.IPAddress;
806
+ for (const net3 of Object.values(networks ?? {})) {
807
+ if (net3?.IPAddress) return net3.IPAddress;
562
808
  }
563
809
  return void 0;
564
810
  }
565
811
  function extractNetworkInfo(data) {
566
812
  let ip;
567
- for (const net2 of Object.values(data.NetworkSettings.Networks ?? {})) {
568
- if (net2.IPAddress) {
569
- ip = net2.IPAddress;
813
+ for (const net3 of Object.values(data.NetworkSettings.Networks ?? {})) {
814
+ if (net3.IPAddress) {
815
+ ip = net3.IPAddress;
570
816
  break;
571
817
  }
572
818
  }
@@ -1225,11 +1471,43 @@ var DockerRuntime = class _DockerRuntime {
1225
1471
  }
1226
1472
  }
1227
1473
  /**
1228
- * Build a STATIC app in a Docker sandbox, then extract its doc-root onto a
1229
- * host directory the edge serves via nginx `root`. Reuses `build()` so
1230
- * Docker is auto-ensured (ensureDockerFeature) and the static nginx image is
1231
- * produced (`generateStaticDockerfile` COPYs the output to the fixed
1232
- * `/usr/share/nginx/html`) then extracts those files and discards the image.
1474
+ * Move an extract-only static build's files out of its builder image onto
1475
+ * `hostOutDir`, then delete the image.
1476
+ *
1477
+ * The ONE place this happens, shared by the single-app path
1478
+ * ({@link buildStaticToHost}) and the compose batch path ({@link buildImages})
1479
+ * they used to be destined to diverge, and the source path is subtle enough
1480
+ * (see `staticBuilderOutputPath`) that two copies would drift into extracting an
1481
+ * empty directory.
1482
+ */
1483
+ async moveStaticBuildToHost(tag, config, hostOutDir, log) {
1484
+ const docRoot = staticBuilderOutputPath(config);
1485
+ const sshExecutor = this.transport.kind === "ssh" ? this.connectionOptions?.executor : null;
1486
+ log.log("Moving built files out of the build container...\n");
1487
+ try {
1488
+ if (sshExecutor) {
1489
+ await this.extractDocRootOverSsh(sshExecutor, tag, docRoot, hostOutDir);
1490
+ } else {
1491
+ await this.extractDocRootViaDaemon(tag, docRoot, hostOutDir);
1492
+ }
1493
+ log.log(`Static files ready at ${hostOutDir}
1494
+ `);
1495
+ } finally {
1496
+ await this.removeImage(tag).catch(() => {
1497
+ });
1498
+ }
1499
+ }
1500
+ /**
1501
+ * Build a STATIC app in a Docker sandbox, then move the built files onto a host
1502
+ * directory the edge serves via nginx `root`. Reuses `build()` so Docker is
1503
+ * auto-ensured (ensureDockerFeature).
1504
+ *
1505
+ * NO RUNTIME IMAGE. `staticExtractOnly` stops the recipe at the builder stage and
1506
+ * the files are copied straight out of it. This used to build a full
1507
+ * `nginx:alpine` runtime stage — pulling that image, running six more steps, and
1508
+ * writing an nginx config nothing reads — only to `docker cp` the doc-root out
1509
+ * and delete the whole thing moments later. The edge already serves these files;
1510
+ * a second web server was never going to run.
1233
1511
  * Returns the host dir as `imageRef`, matching BareRuntime.build's host-dir
1234
1512
  * contract so the existing file-backed serve path (deployStatic /
1235
1513
  * resolveStaticRoot) consumes it unchanged. Never leaves a long-lived
@@ -1237,51 +1515,17 @@ var DockerRuntime = class _DockerRuntime {
1237
1515
  */
1238
1516
  async buildStaticToHost(config, hostOutDir, logger) {
1239
1517
  const log = logger ?? new BuildLogger();
1240
- const buildResult = await this.build({ ...config, isStatic: true }, log);
1518
+ const buildResult = await this.build(
1519
+ { ...config, isStatic: true, staticExtractOnly: true },
1520
+ log
1521
+ );
1241
1522
  if (buildResult.status !== "deploying" || !buildResult.imageRef) {
1242
1523
  return buildResult;
1243
1524
  }
1244
1525
  const tag = buildResult.imageRef;
1245
1526
  const extractStart = Date.now();
1246
- const DOC_ROOT = "/usr/share/nginx/html";
1247
1527
  try {
1248
- const sshExecutor = this.transport.kind === "ssh" ? this.connectionOptions?.executor : null;
1249
- log.log("Extracting static files from the build sandbox...\n");
1250
- if (sshExecutor) {
1251
- const cid = (await sshExecutor.exec(`docker create ${sq(tag)}`)).trim();
1252
- try {
1253
- await sshExecutor.exec(`mkdir -p ${sq(hostOutDir)}`);
1254
- await sshExecutor.exec(`docker cp ${sq(`${cid}:${DOC_ROOT}/.`)} ${sq(hostOutDir)}`);
1255
- } finally {
1256
- await sshExecutor.exec(`docker rm ${sq(cid)}`).catch(() => {
1257
- });
1258
- }
1259
- } else {
1260
- const { mkdir } = await import("fs/promises");
1261
- const { spawn } = await import("child_process");
1262
- await mkdir(hostOutDir, { recursive: true });
1263
- const container = await this.docker.createContainer({ Image: tag });
1264
- try {
1265
- const tarStream = await container.getArchive({ path: DOC_ROOT });
1266
- await new Promise((resolve, reject) => {
1267
- const extract = spawn("tar", ["-x", "--strip-components=1", "-C", hostOutDir]);
1268
- let errBuf = "";
1269
- extract.stderr.on("data", (d) => errBuf += d.toString());
1270
- extract.on("error", reject);
1271
- tarStream.on("error", reject);
1272
- tarStream.pipe(extract.stdin);
1273
- extract.on(
1274
- "close",
1275
- (code) => code === 0 ? resolve() : reject(new Error(`static extract failed (tar ${code}): ${errBuf.trim().slice(-500)}`))
1276
- );
1277
- });
1278
- } finally {
1279
- await container.remove({ force: true }).catch(() => {
1280
- });
1281
- }
1282
- }
1283
- log.log(`Static files ready at ${hostOutDir}
1284
- `);
1528
+ await this.moveStaticBuildToHost(tag, config, hostOutDir, log);
1285
1529
  return {
1286
1530
  sessionId: config.sessionId,
1287
1531
  status: "deploying",
@@ -1297,8 +1541,58 @@ var DockerRuntime = class _DockerRuntime {
1297
1541
  durationMs: (buildResult.durationMs ?? 0) + (Date.now() - extractStart),
1298
1542
  errorMessage: `Static extract failed: ${msg}`
1299
1543
  };
1544
+ }
1545
+ }
1546
+ /**
1547
+ * THE CONTRACT both extractors satisfy: after either one returns, `hostOutDir`
1548
+ * holds the doc-root's CONTENTS directly — `index.html` at the top, no wrapping
1549
+ * `html/` directory. OpenResty's `root` points straight at it, so a stray extra
1550
+ * level is a silent 404 for the whole site.
1551
+ *
1552
+ * The two paths reach that same shape differently, which is why the rule is
1553
+ * stated here once instead of in each branch:
1554
+ * - `docker cp <cid>:<root>/.` — the trailing `/.` means "contents of", so
1555
+ * there is nothing to strip.
1556
+ * - `getArchive({path: <root>})` — the tar IS rooted at `html/`, so exactly
1557
+ * one leading component must be stripped.
1558
+ */
1559
+ /** Remote host: disk-to-disk via the host's own docker CLI — never stream a
1560
+ * large tar over the SSH dockerode bridge (same rationale as saveImage/pullImage). */
1561
+ async extractDocRootOverSsh(sshExecutor, tag, docRoot, hostOutDir) {
1562
+ const cid = (await sshExecutor.exec(`docker create ${sq(tag)}`)).trim();
1563
+ try {
1564
+ await sshExecutor.exec(`mkdir -p ${sq(hostOutDir)}`);
1565
+ await sshExecutor.exec(`docker cp ${sq(`${cid}:${docRoot}/.`)} ${sq(hostOutDir)}`);
1300
1566
  } finally {
1301
- await this.removeImage(tag).catch(() => {
1567
+ await sshExecutor.exec(`docker rm ${sq(cid)}`).catch(() => {
1568
+ });
1569
+ }
1570
+ }
1571
+ /** Local socket / remote TCP: pull the tar through dockerode (portable to a TCP
1572
+ * daemon where a local `docker` CLI wouldn't apply) and extract onto THIS
1573
+ * process's filesystem — in docker-edge mode that's /opt/openship/static,
1574
+ * bind-mounted into both the api and the edge at the same path. */
1575
+ async extractDocRootViaDaemon(tag, docRoot, hostOutDir) {
1576
+ const { mkdir } = await import("fs/promises");
1577
+ const { spawn } = await import("child_process");
1578
+ await mkdir(hostOutDir, { recursive: true });
1579
+ const container = await this.docker.createContainer({ Image: tag });
1580
+ try {
1581
+ const tarStream = await container.getArchive({ path: docRoot });
1582
+ await new Promise((resolve, reject) => {
1583
+ const extract = spawn("tar", ["-x", "--strip-components=1", "-C", hostOutDir]);
1584
+ let errBuf = "";
1585
+ extract.stderr.on("data", (d) => errBuf += d.toString());
1586
+ extract.on("error", reject);
1587
+ tarStream.on("error", reject);
1588
+ tarStream.pipe(extract.stdin);
1589
+ extract.on(
1590
+ "close",
1591
+ (code) => code === 0 ? resolve() : reject(new Error(`static extract failed (tar ${code}): ${errBuf.trim().slice(-500)}`))
1592
+ );
1593
+ });
1594
+ } finally {
1595
+ await container.remove({ force: true }).catch(() => {
1302
1596
  });
1303
1597
  }
1304
1598
  }
@@ -1429,6 +1723,23 @@ var DockerRuntime = class _DockerRuntime {
1429
1723
  await this.streamDockerodeBuild(stream, spec.logger);
1430
1724
  }
1431
1725
  await this.verifyImageBuilt(tag);
1726
+ if (spec.config.staticExtractOnly && spec.config.staticOutDir) {
1727
+ await this.moveStaticBuildToHost(
1728
+ tag,
1729
+ spec.config,
1730
+ spec.config.staticOutDir,
1731
+ spec.logger
1732
+ );
1733
+ const result2 = {
1734
+ sessionId: spec.config.sessionId,
1735
+ status: "deploying",
1736
+ imageRef: spec.config.staticOutDir,
1737
+ durationMs: Date.now() - startedAt
1738
+ };
1739
+ spec.onResult?.(result2);
1740
+ results.push({ serviceName: spec.serviceName, result: result2 });
1741
+ continue;
1742
+ }
1432
1743
  spec.logger.log(`Image ${tag} is ready.
1433
1744
  `);
1434
1745
  const result = {
@@ -2107,8 +2418,8 @@ var DockerRuntime = class _DockerRuntime {
2107
2418
  async getContainerIp(containerId) {
2108
2419
  const container = this.docker.getContainer(containerId);
2109
2420
  const data = await container.inspect();
2110
- for (const net2 of Object.values(data.NetworkSettings.Networks ?? {})) {
2111
- if (net2.IPAddress) return net2.IPAddress;
2421
+ for (const net3 of Object.values(data.NetworkSettings.Networks ?? {})) {
2422
+ if (net3.IPAddress) return net3.IPAddress;
2112
2423
  }
2113
2424
  return null;
2114
2425
  }
@@ -2145,11 +2456,11 @@ var DockerRuntime = class _DockerRuntime {
2145
2456
  Cmd: ["/bin/sh", "-lc", "exec $(command -v bash || echo /bin/sh)"],
2146
2457
  Env: [`TERM=${term}`]
2147
2458
  });
2148
- const duplex = await exec.start({
2149
- hijack: true,
2150
- stdin: true,
2151
- Tty: true
2152
- });
2459
+ const duplex = await startExecStream(
2460
+ daemonConnectionFrom(this.docker),
2461
+ exec.id,
2462
+ { tty: true, stdin: true }
2463
+ );
2153
2464
  try {
2154
2465
  await exec.resize({ h: rows, w: cols });
2155
2466
  } catch {
@@ -2157,6 +2468,7 @@ var DockerRuntime = class _DockerRuntime {
2157
2468
  const stdout = new PassThrough();
2158
2469
  const stderr = new PassThrough();
2159
2470
  duplex.on("data", (chunk) => stdout.write(chunk));
2471
+ duplex.resume();
2160
2472
  duplex.on("end", () => {
2161
2473
  stdout.end();
2162
2474
  stderr.end();
@@ -1,12 +1,14 @@
1
+ #!/usr/bin/env sh
2
+ ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
1
3
  import { createRequire as __ospCreateRequire } from "node:module";
2
4
  const require = __ospCreateRequire(import.meta.url);
3
5
  import {
4
6
  LocalExecutor
5
- } from "./chunk-SYCZE6FQ.js";
7
+ } from "./chunk-TYVME3XD.js";
6
8
  import {
7
9
  logEntry,
8
10
  sq
9
- } from "./chunk-Z6EKX6CX.js";
11
+ } from "./chunk-FPRHYBY2.js";
10
12
 
11
13
  // ../../packages/adapters/src/system/docker-edge-executor.ts
12
14
  import Dockerode from "dockerode";
@@ -74,6 +76,15 @@ var DockerEdgeExecutor = class {
74
76
  // ── File ops ─────────────────────────────────────────────────────────────
75
77
  // "mounted": the shared volume is in this process's filesystem → node:fs.
76
78
  // "container": reach it through the daemon → `docker exec` in the edge.
79
+ /** Same fileMode split as every other file op — never a bare `docker exec mv`. */
80
+ async rename(from, to) {
81
+ if (this.fileMode === "mounted") {
82
+ await this.files.rename(from, to);
83
+ return;
84
+ }
85
+ const { code, stderr } = await this.run(`mv ${sq(from)} ${sq(to)}`);
86
+ if (code !== 0) throw new Error(stderr.trim() || `Failed to rename ${from}`);
87
+ }
77
88
  async writeFile(path, content) {
78
89
  if (this.fileMode === "mounted") return this.files.writeFile(path, content);
79
90
  const encoded = Buffer.from(content, "utf8").toString("base64");
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env sh
2
+ ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
1
3
  import { createRequire as __ospCreateRequire } from "node:module";
2
4
  const require = __ospCreateRequire(import.meta.url);
3
5
  import {
@@ -6,7 +8,7 @@ import {
6
8
  getLocalShellPath,
7
9
  logEntry,
8
10
  sq
9
- } from "./chunk-Z6EKX6CX.js";
11
+ } from "./chunk-FPRHYBY2.js";
10
12
 
11
13
  // ../../packages/adapters/src/system/local-executor.ts
12
14
  import { exec, spawn } from "child_process";
@@ -14,6 +16,7 @@ import {
14
16
  access,
15
17
  mkdir as fsMkdir,
16
18
  readFile as fsReadFile,
19
+ rename as fsRename,
17
20
  rm as fsRm,
18
21
  writeFile as fsWriteFile
19
22
  } from "fs/promises";
@@ -66,6 +69,9 @@ var LocalExecutor = class {
66
69
  await fsMkdir(dirname(path), { recursive: true });
67
70
  await fsWriteFile(path, content, "utf-8");
68
71
  }
72
+ async rename(from, to) {
73
+ await fsRename(from, to);
74
+ }
69
75
  async readFile(path) {
70
76
  return fsReadFile(path, "utf-8");
71
77
  }