openship 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -24
- package/dist/bare-2HYDXQEH.js +23 -0
- package/dist/{bowser-L6PVH37V.js → bowser-O3AEA6AN.js} +3 -1
- package/dist/{chunk-R74UB4X4.js → chunk-2ZLR7ULL.js} +253 -65
- package/dist/{chunk-E3ZPCNPU.js → chunk-3JQTL4R4.js} +234 -99
- package/dist/{chunk-YFLQGDN2.js → chunk-4TJC4JZQ.js} +18 -9
- package/dist/{chunk-JXQCFTDV.js → chunk-4Z5QO7N6.js} +4 -2
- package/dist/{chunk-7EYFCKZX.js → chunk-5FNIWBFI.js} +8 -6
- package/dist/{chunk-JJVSOE4I.js → chunk-5MZ624VX.js} +2 -0
- package/dist/{chunk-TDFK6ISF.js → chunk-6APIPIJY.js} +6 -4
- package/dist/{chunk-3LCRNQ2C.js → chunk-6APULWSU.js} +151 -133
- package/dist/{chunk-FTBXJ2VA.js → chunk-6B5YCFFV.js} +6 -4
- package/dist/{chunk-MDFYN2QH.js → chunk-AVIB7CT7.js} +3 -1
- package/dist/{chunk-VJTXRCTT.js → chunk-C5OHTYEF.js} +10 -6
- package/dist/{chunk-W7KGHYLV.js → chunk-DYPH4HCI.js} +2 -0
- package/dist/{chunk-5WI7ZXOC.js → chunk-EI575GHN.js} +4 -2
- package/dist/{chunk-Z6EKX6CX.js → chunk-FPRHYBY2.js} +2 -0
- package/dist/chunk-FQGJZ2HS.js +248 -0
- package/dist/{chunk-FZJX6XP7.js → chunk-FRNAR33O.js} +4 -2
- package/dist/{chunk-XRWV5ZNR.js → chunk-FXTBHTWY.js} +360 -42
- package/dist/chunk-ILFETZOM.js +131 -0
- package/dist/{chunk-PARRPUXN.js → chunk-IXCHURVK.js} +5 -3
- package/dist/{chunk-YJAS5RQX.js → chunk-JYGD5WSN.js} +2 -0
- package/dist/{chunk-JWBXYO24.js → chunk-KI2EY3WB.js} +2 -0
- package/dist/{chunk-YVXF6GGR.js → chunk-L2VOGB2X.js} +5 -104
- package/dist/{chunk-K5OH5U7N.js → chunk-MZ2WEHHY.js} +5 -3
- package/dist/{chunk-SJBR527P.js → chunk-O6ZZF52V.js} +3 -1
- package/dist/{chunk-VLPJLXXB.js → chunk-OWED2GRM.js} +3 -1
- package/dist/{chunk-C4FOQJ63.js → chunk-OXWDY22G.js} +4 -2
- package/dist/{chunk-NPVJYR7M.js → chunk-Q2CIRAOK.js} +2 -0
- package/dist/{chunk-JYAGTMSJ.js → chunk-RPHRPFEH.js} +2 -0
- package/dist/{chunk-UMYQALBH.js → chunk-SQ77DZOI.js} +1726 -1484
- package/dist/{chunk-HYL4QYZM.js → chunk-TGIINPVM.js} +13 -2
- package/dist/{chunk-SYCZE6FQ.js → chunk-TYVME3XD.js} +7 -1
- package/dist/{chunk-HDV4NSA3.js → chunk-V6AN6XLZ.js} +16 -6
- package/dist/{chunk-3YCMJRDZ.js → chunk-VDMQJHPI.js} +36 -15
- package/dist/{chunk-RZPDJC2J.js → chunk-VFINNTUL.js} +20 -1
- package/dist/{chunk-65KKUJBR.js → chunk-VWPEKOH6.js} +4 -2
- package/dist/{chunk-GHXGCANU.js → chunk-W73X43R7.js} +4 -2
- package/dist/{cloud-7IGG45CF.js → cloud-7QYOGF7F.js} +4 -2
- package/dist/cloud-ZSKOS4GY.js +30 -0
- package/dist/detect-SH4FHFBI.js +36 -0
- package/dist/{dist-NQB6QGX3.js → dist-IQJ6H6UZ.js} +4 -2
- package/dist/{dist-es-DCR6UJMP.js → dist-es-5DY7K32L.js} +7 -5
- package/dist/{dist-es-TYYZ5KEF.js → dist-es-JSTDUS7Q.js} +7 -5
- package/dist/{dist-es-7EZIM4JU.js → dist-es-OSNJBLXB.js} +6 -4
- package/dist/{dist-es-6RSPR56Q.js → dist-es-RYHIPOTN.js} +15 -13
- package/dist/{dist-es-33Z3Y6VE.js → dist-es-VNKHQVIB.js} +5 -3
- package/dist/{dist-es-D6QQVWRZ.js → dist-es-WV4AMOII.js} +9 -7
- package/dist/{dist-es-GMEQINIE.js → dist-es-X3B5QYKB.js} +7 -5
- package/dist/docker-U7AF5PTA.js +16 -0
- package/dist/docker-edge-executor-VHW3JPJS.js +13 -0
- package/dist/edge-import-V5CBA47C.js +45 -0
- package/dist/ensure-container-edge-CMYROUSI.js +33 -0
- package/dist/{event-streams-G7F6Q7QY.js → event-streams-EHRAKL75.js} +5 -3
- package/dist/{executor-O5NR7LMP.js → executor-YPT6RH6O.js} +9 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +256 -245
- package/dist/{loadSso-LH753OSJ.js → loadSso-46FQRIZS.js} +11 -9
- package/dist/local-executor-V7U5VOZW.js +12 -0
- package/dist/nginx-2GTRUIDE.js +24 -0
- package/dist/{noop-6KC6HRDB.js → noop-FMMFG2EZ.js} +4 -2
- package/dist/{openresty-lua-KFCOJAG4.js → openresty-lua-4WLGDSER.js} +11 -3
- package/dist/server/engine/ChangeLog +2289 -0
- package/dist/server/engine/Documentations +5 -0
- package/dist/server/engine/LICENSE +674 -0
- package/dist/server/engine/README.md +34 -0
- package/dist/server/engine/conf/amavisd +150 -0
- package/dist/server/engine/conf/clamav +71 -0
- package/dist/server/engine/conf/core +632 -0
- package/dist/server/engine/conf/dovecot +151 -0
- package/dist/server/engine/conf/fail2ban +72 -0
- package/dist/server/engine/conf/global +698 -0
- package/dist/server/engine/conf/iredapd +52 -0
- package/dist/server/engine/conf/logwatch +28 -0
- package/dist/server/engine/conf/postfix +97 -0
- package/dist/server/engine/conf/postgresql +93 -0
- package/dist/server/engine/conf/spamassassin +39 -0
- package/dist/server/engine/dialog/config_via_dialog.sh +258 -0
- package/dist/server/engine/dialog/optional_components.sh +122 -0
- package/dist/server/engine/dialog/pgsql_config.sh +52 -0
- package/dist/server/engine/dialog/virtual_domain_config.sh +94 -0
- package/dist/server/engine/functions/amavisd.sh +267 -0
- package/dist/server/engine/functions/backend.sh +85 -0
- package/dist/server/engine/functions/clamav.sh +100 -0
- package/dist/server/engine/functions/cleanup.sh +393 -0
- package/dist/server/engine/functions/dovecot.sh +583 -0
- package/dist/server/engine/functions/fail2ban.sh +209 -0
- package/dist/server/engine/functions/iredapd.sh +356 -0
- package/dist/server/engine/functions/optional_components.sh +24 -0
- package/dist/server/engine/functions/packages.sh +522 -0
- package/dist/server/engine/functions/packages_freebsd.sh +179 -0
- package/dist/server/engine/functions/postfix.sh +457 -0
- package/dist/server/engine/functions/postgresql.sh +239 -0
- package/dist/server/engine/functions/spamassassin.sh +49 -0
- package/dist/server/engine/functions/system_accounts.sh +128 -0
- package/dist/server/engine/iRedMail.sh +144 -0
- package/dist/server/engine/pkgs/get_all.sh +338 -0
- package/dist/server/engine/pkgs/pkgs.freebsd.sha256 +3 -0
- package/dist/server/engine/pkgs/pkgs.openbsd.sha256 +6 -0
- package/dist/server/engine/pkgs/pkgs.sha256 +1 -0
- package/dist/server/engine/samples/amavisd/amavisd.conf +677 -0
- package/dist/server/engine/samples/amavisd/amavisd.mysql +278 -0
- package/dist/server/engine/samples/amavisd/amavisd.pgsql +253 -0
- package/dist/server/engine/samples/amavisd/amavisd.schema +942 -0
- package/dist/server/engine/samples/amavisd/default_spam_policy.sql +46 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-mariadb.conf +758 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-openldap.conf +767 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-pgsql.conf +762 -0
- package/dist/server/engine/samples/dovecot/dovecot-last-login.conf +50 -0
- package/dist/server/engine/samples/dovecot/dovecot-ldap.conf +21 -0
- package/dist/server/engine/samples/dovecot/dovecot-share-folder.conf +22 -0
- package/dist/server/engine/samples/dovecot/dovecot-sql.conf +28 -0
- package/dist/server/engine/samples/dovecot/dovecot-used-quota.conf +13 -0
- package/dist/server/engine/samples/dovecot/dovecot.conf +484 -0
- package/dist/server/engine/samples/dovecot/dovecot.sieve +7 -0
- package/dist/server/engine/samples/dovecot/dovecot2-quota-warning.sh +38 -0
- package/dist/server/engine/samples/dovecot/sql/imap_share_folder.mysql +16 -0
- package/dist/server/engine/samples/dovecot/sql/last_login.mysql +12 -0
- package/dist/server/engine/samples/dovecot/sql/used_quota.mysql +26 -0
- package/dist/server/engine/samples/dovecot/systemd/override.conf +3 -0
- package/dist/server/engine/samples/fail2ban/action.d/banned_db.conf +9 -0
- package/dist/server/engine/samples/fail2ban/bin/fail2ban_banned_db +268 -0
- package/dist/server/engine/samples/fail2ban/fail2ban.local +17 -0
- package/dist/server/engine/samples/fail2ban/filter.d/dovecot.iredmail.conf +5 -0
- package/dist/server/engine/samples/fail2ban/filter.d/postfix-pregreet.iredmail.conf +16 -0
- package/dist/server/engine/samples/fail2ban/filter.d/postfix.iredmail.conf +18 -0
- package/dist/server/engine/samples/fail2ban/filter.d/roundcube.iredmail.conf +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/dovecot.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/nginx-http-auth.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/postfix-pregreet.local +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/postfix.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/roundcube.local +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/sogo.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/sshd.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.local +6 -0
- package/dist/server/engine/samples/fail2ban/openbsd/rc +27 -0
- package/dist/server/engine/samples/fail2ban/sql/fail2ban.mysql +49 -0
- package/dist/server/engine/samples/fail2ban/sql/fail2ban.pgsql +48 -0
- package/dist/server/engine/samples/firewall/firewalld/services/ssh.xml +6 -0
- package/dist/server/engine/samples/firewall/firewalld/zones/iredmail.xml +15 -0
- package/dist/server/engine/samples/firewall/iptables/ip6tables.init.debian +362 -0
- package/dist/server/engine/samples/firewall/iptables/ip6tables.rules +53 -0
- package/dist/server/engine/samples/firewall/iptables/iptables.init.debian +363 -0
- package/dist/server/engine/samples/firewall/iptables/iptables.rules +54 -0
- package/dist/server/engine/samples/firewall/nftables.conf +58 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/dovecot.conf +3 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/iredapd.conf +1 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/mlmmjadmin.conf +1 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/php-fpm.conf +2 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/slapd.conf +1 -0
- package/dist/server/engine/samples/freebsd/syslog.d/dovecot.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/fail2ban.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/iredapd.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/mlmmjadmin.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/php-fpm.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/slapd.conf +2 -0
- package/dist/server/engine/samples/iredmail/iredmail.mysql +491 -0
- package/dist/server/engine/samples/iredmail/iredmail.pgsql +465 -0
- package/dist/server/engine/samples/iredmail/iredmail.schema +456 -0
- package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.3.pgsql +40 -0
- package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.4.pgsql +18 -0
- package/dist/server/engine/samples/logrotate/dovecot +13 -0
- package/dist/server/engine/samples/logrotate/iredapd +13 -0
- package/dist/server/engine/samples/logrotate/mlmmjadmin +13 -0
- package/dist/server/engine/samples/logrotate/openldap +19 -0
- package/dist/server/engine/samples/logrotate/php-fpm +13 -0
- package/dist/server/engine/samples/openbsd/ldapd.conf +58 -0
- package/dist/server/engine/samples/openbsd/pf.conf +28 -0
- package/dist/server/engine/samples/postfix/command_filter.pcre +3 -0
- package/dist/server/engine/samples/postfix/freebsd/mailer.conf +9 -0
- package/dist/server/engine/samples/postfix/helo_access.pcre +180 -0
- package/dist/server/engine/samples/postfix/ldap/catchall_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/relay_domains.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_login_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/transport_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/transport_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_alias_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_group_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_group_members_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_domains.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_maps.cf +12 -0
- package/dist/server/engine/samples/postfix/main.cf +282 -0
- package/dist/server/engine/samples/postfix/main.cf.amavisd +7 -0
- package/dist/server/engine/samples/postfix/main.cf.dovecot +8 -0
- package/dist/server/engine/samples/postfix/main.cf.ldap +39 -0
- package/dist/server/engine/samples/postfix/main.cf.mlmmj +5 -0
- package/dist/server/engine/samples/postfix/main.cf.mysql +39 -0
- package/dist/server/engine/samples/postfix/main.cf.pgsql +39 -0
- package/dist/server/engine/samples/postfix/main.cf.postscreen +30 -0
- package/dist/server/engine/samples/postfix/master.cf +87 -0
- package/dist/server/engine/samples/postfix/mysql/catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/domain_alias_catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/domain_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/relay_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_dependent_relayhost_maps.cf +6 -0
- package/dist/server/engine/samples/postfix/mysql/sender_login_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_maillist.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/domain_alias_catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/domain_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/relay_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_dependent_relayhost_maps.cf +6 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_login_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_maillist.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/postscreen_access.cidr +6 -0
- package/dist/server/engine/samples/postgresql/sql/add_first_domain_and_user.sql +34 -0
- package/dist/server/engine/samples/postgresql/sql/grant_permissions.sql +14 -0
- package/dist/server/engine/samples/postgresql/sql/init_vmail_db.sql +15 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-dovecot.conf +23 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-fail2ban.conf +2 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-iredapd.conf +12 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-mlmmjadmin.conf +12 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-openldap.conf +2 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-phpfpm.conf +3 -0
- package/dist/server/engine/samples/spamassassin/local.cf +186 -0
- package/dist/server/engine/samples/spamassassin/razor.conf +1 -0
- package/dist/server/engine/samples/systemd/clamd.service.d/override.conf +2 -0
- package/dist/server/engine/samples/systemd/mariadb.service.d/override.conf +3 -0
- package/dist/server/engine/samples/systemd/slapd.service.d/override.conf +6 -0
- package/dist/server/engine/samples/yum/CentOS-Linux-AppStream.repo +6 -0
- package/dist/server/engine/samples/yum/CentOS-Linux-PowerTools.repo +6 -0
- package/dist/server/engine/samples/yum/CentOS-Stream-AppStream.repo +7 -0
- package/dist/server/engine/samples/yum/CentOS-Stream-PowerTools.repo +7 -0
- package/dist/server/engine/samples/yum/symas-openldap.repo +6 -0
- package/dist/server/engine/tools/add_enabled_service.py +60 -0
- package/dist/server/engine/tools/backup_mysql.sh +238 -0
- package/dist/server/engine/tools/backup_openldap.sh +230 -0
- package/dist/server/engine/tools/backup_pgsql.sh +217 -0
- package/dist/server/engine/tools/backup_sogo.sh +156 -0
- package/dist/server/engine/tools/create_mail_user_OpenLDAP.py +335 -0
- package/dist/server/engine/tools/create_mail_user_OpenLDAP.sh +287 -0
- package/dist/server/engine/tools/create_mail_user_SQL.sh +127 -0
- package/dist/server/engine/tools/enable_postscreen.sh +144 -0
- package/dist/server/engine/tools/fail2ban_unban_ip.sh +39 -0
- package/dist/server/engine/tools/find_sasl_login_ip.sh +20 -0
- package/dist/server/engine/tools/find_top_sasl_usernames.sh +28 -0
- package/dist/server/engine/tools/generate_ssl_keys.sh +85 -0
- package/dist/server/engine/tools/kill_high_cpu_sogo_process.sh +32 -0
- package/dist/server/engine/tools/ldap_assign_user_to_groups.py +151 -0
- package/dist/server/engine/tools/ldap_move_members_to_another_group.py +129 -0
- package/dist/server/engine/tools/migrate_sql_alias_table.py +177 -0
- package/dist/server/engine/update/0.9.8/amavisd.mysql +29 -0
- package/dist/server/engine/update/0.9.8/amavisd.pgsql +39 -0
- package/dist/server/engine/update/0.9.8/iredmail.mysql +53 -0
- package/dist/server/engine/update/0.9.8/iredmail.pgsql +61 -0
- package/dist/server/engine/update/0.9.9/iredmail.mysql +2 -0
- package/dist/server/engine/update/0.9.9/iredmail.pgsql +2 -0
- package/dist/server/engine/update/1.0/iredmail.mysql +2 -0
- package/dist/server/engine/update/1.0/iredmail.pgsql +2 -0
- package/dist/server/engine/update/1.2/last_login.mysql +16 -0
- package/dist/server/engine/update/1.4.0/iredmail.mysql +22 -0
- package/dist/server/engine/update/1.4.0/iredmail.pgsql +20 -0
- package/dist/server/engine/update/1.4.1/iredmail.mysql +3 -0
- package/dist/server/engine/update/1.4.1/iredmail.pgsql +3 -0
- package/dist/server/engine/update/1.4.1/sogo.mysql +11 -0
- package/dist/server/engine/update/1.4.1/sogo.pgsql +30 -0
- package/dist/server/engine/update/1.4.1/update-ldap.py +66 -0
- package/dist/server/engine/update/1.4.2/iredmail.mysql +9 -0
- package/dist/server/engine/update/1.4.2/iredmail.pgsql +9 -0
- package/dist/server/engine/update/1.4.2/sogo.pgsql +30 -0
- package/dist/server/engine/update/1.6.0/sogo_view.pgsql +27 -0
- package/dist/server/engine/update/1.6.3/iredmail.mysql +1 -0
- package/dist/server/engine/update/1.7.0/fail2ban.mysql +11 -0
- package/dist/server/engine/update/1.7.0/fail2ban.pgsql +12 -0
- package/dist/server/engine/update/1.7.1/amavisd.mysql +1 -0
- package/dist/server/engine/update/1.7.2/vmail.mysql +30 -0
- package/dist/server/engine/update/1.7.3/deleted_mailboxes.mysql +43 -0
- package/dist/server/engine/update/1.7.3/iredadmin.mysql +26 -0
- package/dist/server/engine/update/1.7.3/vmail.mysql +79 -0
- package/dist/server/engine/update/1.7.3/vmail.pgsql +9 -0
- package/dist/server/engine/update/README.md +1 -0
- package/dist/server/engine/update/ldap/README.md +40 -0
- package/dist/server/engine/update/ldap/update-ldap-dovecot-2.3.py +69 -0
- package/dist/server/index.js +55574 -53675
- package/dist/server/migrations/0071_gh_device_token.sql +3 -0
- package/dist/server/migrations/0072_gh_device_token_method.sql +1 -0
- package/dist/server/migrations/meta/_journal.json +14 -0
- package/dist/setup-HQIZLUOJ.js +20 -0
- package/dist/{signin-PVC7MBZJ.js → signin-ITOPKKUB.js} +11 -9
- package/dist/{sso-oidc-ZXY77BSL.js → sso-oidc-NON2PD7Y.js} +11 -9
- package/dist/{sts-LX5L4UU3.js → sts-HHFFSAY2.js} +10 -8
- package/package.json +1 -1
- package/dist/bare-CNSFDNSZ.js +0 -20
- package/dist/cloud-655YYCEW.js +0 -26
- package/dist/docker-UWQPDEGW.js +0 -14
- package/dist/docker-edge-executor-ZLAYE5FE.js +0 -11
- package/dist/edge-import-AFID2EN3.js +0 -41
- package/dist/nginx-M36GDYL7.js +0 -18
- package/dist/setup-ZXXB5S22.js +0 -16
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
|
|
2
3
|
import { createRequire as __ospCreateRequire } from "node:module";
|
|
3
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
4
5
|
import {
|
|
@@ -8,6 +9,9 @@ import {
|
|
|
8
9
|
composeInternalToken,
|
|
9
10
|
composeIsViableDefault,
|
|
10
11
|
composePs,
|
|
12
|
+
composeRestart,
|
|
13
|
+
composeRunning,
|
|
14
|
+
composeStart,
|
|
11
15
|
composeUninstall,
|
|
12
16
|
composeUp,
|
|
13
17
|
composeUpdate,
|
|
@@ -21,47 +25,54 @@ import {
|
|
|
21
25
|
remoteSha,
|
|
22
26
|
shortSha,
|
|
23
27
|
sourceBuildDir
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
34
|
-
import "./chunk-
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-R74UB4X4.js";
|
|
39
|
-
import "./chunk-3YCMJRDZ.js";
|
|
40
|
-
import "./chunk-7EYFCKZX.js";
|
|
28
|
+
} from "./chunk-3JQTL4R4.js";
|
|
29
|
+
import "./chunk-FRNAR33O.js";
|
|
30
|
+
import "./chunk-EI575GHN.js";
|
|
31
|
+
import "./chunk-6APIPIJY.js";
|
|
32
|
+
import "./chunk-IXCHURVK.js";
|
|
33
|
+
import "./chunk-OWED2GRM.js";
|
|
34
|
+
import "./chunk-VWPEKOH6.js";
|
|
35
|
+
import "./chunk-W73X43R7.js";
|
|
36
|
+
import "./chunk-TGIINPVM.js";
|
|
37
|
+
import "./chunk-5FNIWBFI.js";
|
|
38
|
+
import "./chunk-AVIB7CT7.js";
|
|
39
|
+
import "./chunk-5MZ624VX.js";
|
|
40
|
+
import "./chunk-Q2CIRAOK.js";
|
|
41
|
+
import "./chunk-C5OHTYEF.js";
|
|
41
42
|
import {
|
|
42
43
|
beginEdgeTakeover,
|
|
44
|
+
collectProxyCerts,
|
|
43
45
|
completeEdgeTakeover,
|
|
44
46
|
detectInstalledProxy,
|
|
47
|
+
edgeProxy,
|
|
48
|
+
edgeProxyFor,
|
|
45
49
|
foreignProxyOnEdge,
|
|
46
50
|
importSites,
|
|
47
|
-
ourEdgeContainerRunning,
|
|
48
51
|
recoverInterruptedTakeover,
|
|
49
52
|
rollbackEdgeTakeover,
|
|
50
53
|
scanImportableSites
|
|
51
|
-
} from "./chunk-
|
|
52
|
-
import "./chunk-
|
|
53
|
-
import "./chunk-
|
|
54
|
-
import "./chunk-
|
|
55
|
-
import "./chunk-
|
|
56
|
-
import "./chunk-
|
|
54
|
+
} from "./chunk-SQ77DZOI.js";
|
|
55
|
+
import "./chunk-O6ZZF52V.js";
|
|
56
|
+
import "./chunk-JYGD5WSN.js";
|
|
57
|
+
import "./chunk-2ZLR7ULL.js";
|
|
58
|
+
import "./chunk-V6AN6XLZ.js";
|
|
59
|
+
import "./chunk-VDMQJHPI.js";
|
|
60
|
+
import "./chunk-MZ2WEHHY.js";
|
|
61
|
+
import "./chunk-L2VOGB2X.js";
|
|
62
|
+
import "./chunk-4Z5QO7N6.js";
|
|
63
|
+
import "./chunk-4TJC4JZQ.js";
|
|
64
|
+
import "./chunk-OXWDY22G.js";
|
|
65
|
+
import "./chunk-RPHRPFEH.js";
|
|
57
66
|
import {
|
|
58
67
|
LocalExecutor
|
|
59
|
-
} from "./chunk-
|
|
60
|
-
import "./chunk-
|
|
61
|
-
import "./chunk-
|
|
62
|
-
import
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
} from "./chunk-TYVME3XD.js";
|
|
69
|
+
import "./chunk-FXTBHTWY.js";
|
|
70
|
+
import "./chunk-FPRHYBY2.js";
|
|
71
|
+
import {
|
|
72
|
+
ourEdgeContainerRunning
|
|
73
|
+
} from "./chunk-FQGJZ2HS.js";
|
|
74
|
+
import "./chunk-ILFETZOM.js";
|
|
75
|
+
import "./chunk-VFINNTUL.js";
|
|
65
76
|
import {
|
|
66
77
|
CLOUD_DASHBOARD_URL,
|
|
67
78
|
LOCAL_API_URL,
|
|
@@ -70,9 +81,8 @@ import {
|
|
|
70
81
|
isValidEmail,
|
|
71
82
|
parseOpenshipConfigJson,
|
|
72
83
|
resolveCliUpdatePlan
|
|
73
|
-
} from "./chunk-
|
|
74
|
-
import "./chunk-
|
|
75
|
-
import "./chunk-JWBXYO24.js";
|
|
84
|
+
} from "./chunk-6APULWSU.js";
|
|
85
|
+
import "./chunk-KI2EY3WB.js";
|
|
76
86
|
|
|
77
87
|
// src/index.ts
|
|
78
88
|
import { Command as Command28 } from "commander";
|
|
@@ -474,7 +484,7 @@ import chalk6 from "chalk";
|
|
|
474
484
|
import ora from "ora";
|
|
475
485
|
import { spawn } from "child_process";
|
|
476
486
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
477
|
-
import { createWriteStream as createWriteStream2, existsSync as existsSync7, mkdirSync as mkdirSync8, readFileSync as
|
|
487
|
+
import { createWriteStream as createWriteStream2, existsSync as existsSync7, mkdirSync as mkdirSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
478
488
|
import { dirname as dirname2, join as join8 } from "path";
|
|
479
489
|
import { fileURLToPath } from "url";
|
|
480
490
|
|
|
@@ -1000,20 +1010,10 @@ async function resolvePorts(prefs) {
|
|
|
1000
1010
|
|
|
1001
1011
|
// src/lib/edge-preflight.ts
|
|
1002
1012
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
1003
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync6,
|
|
1013
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1004
1014
|
import { join as join6 } from "path";
|
|
1005
1015
|
import chalk5 from "chalk";
|
|
1006
1016
|
import { isCancel, log, note, select } from "@clack/prompts";
|
|
1007
|
-
function isSafePath(p) {
|
|
1008
|
-
return /^\/[A-Za-z0-9._/-]+$/.test(p);
|
|
1009
|
-
}
|
|
1010
|
-
function readCertFile(p) {
|
|
1011
|
-
try {
|
|
1012
|
-
return readFileSync4(p, "utf8");
|
|
1013
|
-
} catch {
|
|
1014
|
-
return null;
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
1017
|
async function planAndApplyHostEdge(opts, overrides = {}) {
|
|
1018
1018
|
const deps = { ...defaultDeps(), ...overrides };
|
|
1019
1019
|
if (deps.platform !== "linux") return { proceed: true };
|
|
@@ -1031,7 +1031,7 @@ async function planAndApplyHostEdge(opts, overrides = {}) {
|
|
|
1031
1031
|
const { sites, warnings } = await deps.importSites(executor, status);
|
|
1032
1032
|
const action2 = await resolveAction(opts.edge, { status, owner, sites, warnings }, deps);
|
|
1033
1033
|
if (action2 === "cancel") return { proceed: false };
|
|
1034
|
-
const certPems = action2 === "migrate" ?
|
|
1034
|
+
const certPems = action2 === "migrate" ? await deps.collectCerts(executor, sites, { status }) : void 0;
|
|
1035
1035
|
await deps.beginEdgeTakeover(
|
|
1036
1036
|
executor,
|
|
1037
1037
|
status,
|
|
@@ -1108,7 +1108,12 @@ async function offerStoppedProxyImport(executor, deps) {
|
|
|
1108
1108
|
if (!await deps.confirmStoppedImport({ proxy, count: sites.length })) {
|
|
1109
1109
|
return { proceed: true };
|
|
1110
1110
|
}
|
|
1111
|
-
return {
|
|
1111
|
+
return {
|
|
1112
|
+
proceed: true,
|
|
1113
|
+
action: "migrate",
|
|
1114
|
+
sites,
|
|
1115
|
+
certPems: await deps.collectCerts(executor, sites, { proxy })
|
|
1116
|
+
};
|
|
1112
1117
|
}
|
|
1113
1118
|
async function completeHostEdge() {
|
|
1114
1119
|
if (process.platform !== "linux") return;
|
|
@@ -1132,17 +1137,57 @@ async function resolveAction(flag, ctx, deps) {
|
|
|
1132
1137
|
importable: ctx.sites.length
|
|
1133
1138
|
});
|
|
1134
1139
|
}
|
|
1135
|
-
function
|
|
1136
|
-
const
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1140
|
+
async function collectCertsFromProxy(executor, sites, source) {
|
|
1141
|
+
const api = source.proxy ? edgeProxyFor(executor, source.proxy) : await edgeProxy(executor, source.status ? { status: source.status } : {});
|
|
1142
|
+
if (!api) return {};
|
|
1143
|
+
const { certPems, warnings } = await collectProxyCerts(api, sites);
|
|
1144
|
+
for (const w of warnings) console.log(chalk5.yellow(` ${w}`));
|
|
1145
|
+
return certPems;
|
|
1146
|
+
}
|
|
1147
|
+
function renderEdgeConflict(info3) {
|
|
1148
|
+
const { owner, sites, warnings } = info3;
|
|
1149
|
+
if (sites.length > 0) {
|
|
1150
|
+
const lines = sites.map((st) => {
|
|
1151
|
+
const host = (st.serverNames ?? []).join(", ") || "(no server_name)";
|
|
1152
|
+
const dest = st.target.kind === "static" ? `static: ${st.target.root}` : st.target.url;
|
|
1153
|
+
return `${chalk5.bold(host)} \u2192 ${chalk5.dim(dest)}${st.ssl ? chalk5.green(" [TLS]") : ""}`;
|
|
1154
|
+
});
|
|
1155
|
+
note(lines.join("\n"), `Detected ${sites.length} site${sites.length === 1 ? "" : "s"} on ${owner}`);
|
|
1156
|
+
}
|
|
1157
|
+
if (warnings.length > 0) {
|
|
1158
|
+
log.warn(`${warnings.length} config item${warnings.length === 1 ? "" : "s"} won't migrate automatically:`);
|
|
1159
|
+
for (const w of warnings.slice(0, 8)) log.message(chalk5.dim(`\u2022 ${w}`));
|
|
1144
1160
|
}
|
|
1145
|
-
|
|
1161
|
+
}
|
|
1162
|
+
async function confirmEdgeAction(info3) {
|
|
1163
|
+
const { owner, known, importable } = info3;
|
|
1164
|
+
const choice = await select({
|
|
1165
|
+
message: known ? `An existing reverse proxy (${owner}) is serving ports 80/443.` : `Ports 80/443 are in use by ${owner}, which we couldn't identify.`,
|
|
1166
|
+
options: [
|
|
1167
|
+
...importable > 0 ? [
|
|
1168
|
+
{
|
|
1169
|
+
value: "migrate",
|
|
1170
|
+
label: `Migrate ${importable} site${importable === 1 ? "" : "s"} & take over`,
|
|
1171
|
+
hint: "import the existing sites into Openship's edge, then take 80/443"
|
|
1172
|
+
}
|
|
1173
|
+
] : [],
|
|
1174
|
+
{
|
|
1175
|
+
value: "takeover",
|
|
1176
|
+
label: "Stop it & take over 80/443",
|
|
1177
|
+
hint: known ? "the existing sites stop being served" : "may interrupt a running service"
|
|
1178
|
+
},
|
|
1179
|
+
{ value: "cancel", label: "Cancel \u2014 leave it running" }
|
|
1180
|
+
],
|
|
1181
|
+
// Default to MIGRATE whenever there are sites we can import: it's the only
|
|
1182
|
+
// option that both gets Openship onto 80/443 and keeps the operator's
|
|
1183
|
+
// existing sites served, so it's the choice they almost always want and
|
|
1184
|
+
// the one that loses nothing on a reflexive Enter.
|
|
1185
|
+
// With nothing importable there's no safe default: a known proxy falls
|
|
1186
|
+
// back to cancel (blind Enter would stop sites that are being served),
|
|
1187
|
+
// and an unidentified port holder to takeover.
|
|
1188
|
+
initialValue: importable > 0 ? "migrate" : known ? "cancel" : "takeover"
|
|
1189
|
+
});
|
|
1190
|
+
return isCancel(choice) ? "cancel" : choice;
|
|
1146
1191
|
}
|
|
1147
1192
|
function defaultDeps() {
|
|
1148
1193
|
return {
|
|
@@ -1172,61 +1217,20 @@ function defaultDeps() {
|
|
|
1172
1217
|
});
|
|
1173
1218
|
return !isCancel(take) && take === "import";
|
|
1174
1219
|
},
|
|
1175
|
-
|
|
1176
|
-
render:
|
|
1177
|
-
|
|
1178
|
-
const lines = sites.map((st) => {
|
|
1179
|
-
const host = (st.serverNames ?? []).join(", ") || "(no server_name)";
|
|
1180
|
-
const dest = st.target.kind === "static" ? `static: ${st.target.root}` : st.target.url;
|
|
1181
|
-
return `${chalk5.bold(host)} \u2192 ${chalk5.dim(dest)}${st.ssl ? chalk5.green(" [TLS]") : ""}`;
|
|
1182
|
-
});
|
|
1183
|
-
note(lines.join("\n"), `Detected ${sites.length} site${sites.length === 1 ? "" : "s"} on ${owner}`);
|
|
1184
|
-
}
|
|
1185
|
-
if (warnings.length > 0) {
|
|
1186
|
-
log.warn(`${warnings.length} config item${warnings.length === 1 ? "" : "s"} won't migrate automatically:`);
|
|
1187
|
-
for (const w of warnings.slice(0, 8)) log.message(chalk5.dim(`\u2022 ${w}`));
|
|
1188
|
-
}
|
|
1189
|
-
},
|
|
1190
|
-
confirm: async ({ owner, known, importable }) => {
|
|
1191
|
-
const choice = await select({
|
|
1192
|
-
message: known ? `An existing reverse proxy (${owner}) is serving ports 80/443.` : `Ports 80/443 are in use by ${owner}, which we couldn't identify.`,
|
|
1193
|
-
options: [
|
|
1194
|
-
...importable > 0 ? [
|
|
1195
|
-
{
|
|
1196
|
-
value: "migrate",
|
|
1197
|
-
label: `Migrate ${importable} site${importable === 1 ? "" : "s"} & take over`,
|
|
1198
|
-
hint: "import the existing sites into Openship's edge, then take 80/443"
|
|
1199
|
-
}
|
|
1200
|
-
] : [],
|
|
1201
|
-
{
|
|
1202
|
-
value: "takeover",
|
|
1203
|
-
label: "Stop it & take over 80/443",
|
|
1204
|
-
hint: known ? "the existing sites stop being served" : "may interrupt a running service"
|
|
1205
|
-
},
|
|
1206
|
-
{ value: "cancel", label: "Cancel \u2014 leave it running" }
|
|
1207
|
-
],
|
|
1208
|
-
// Default to MIGRATE whenever there are sites we can import: it's the only
|
|
1209
|
-
// option that both gets Openship onto 80/443 and keeps the operator's
|
|
1210
|
-
// existing sites served, so it's the choice they almost always want and
|
|
1211
|
-
// the one that loses nothing on a reflexive Enter.
|
|
1212
|
-
// With nothing importable there's no safe default: a known proxy falls
|
|
1213
|
-
// back to cancel (blind Enter would stop sites that are being served),
|
|
1214
|
-
// and an unidentified port holder to takeover.
|
|
1215
|
-
initialValue: importable > 0 ? "migrate" : known ? "cancel" : "takeover"
|
|
1216
|
-
});
|
|
1217
|
-
return isCancel(choice) ? "cancel" : choice;
|
|
1218
|
-
},
|
|
1220
|
+
collectCerts: collectCertsFromProxy,
|
|
1221
|
+
render: renderEdgeConflict,
|
|
1222
|
+
confirm: confirmEdgeAction,
|
|
1219
1223
|
warn: (message) => console.log(chalk5.yellow(` ${message}`))
|
|
1220
1224
|
};
|
|
1221
1225
|
}
|
|
1222
1226
|
|
|
1223
1227
|
// src/lib/loopback-api.ts
|
|
1224
|
-
import { existsSync as existsSync6, readFileSync as
|
|
1228
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
1225
1229
|
import { randomBytes } from "crypto";
|
|
1226
1230
|
import { join as join7 } from "path";
|
|
1227
1231
|
function ensureInternalToken() {
|
|
1228
1232
|
const path2 = join7(OS_DIR, "internal-token");
|
|
1229
|
-
if (existsSync6(path2)) return
|
|
1233
|
+
if (existsSync6(path2)) return readFileSync4(path2, "utf8").trim();
|
|
1230
1234
|
mkdirSync7(OS_DIR, { recursive: true, mode: 448 });
|
|
1231
1235
|
const token = randomBytes(32).toString("hex");
|
|
1232
1236
|
writeFileSync6(path2, token, { mode: 384 });
|
|
@@ -1486,26 +1490,31 @@ async function headlessProvision(opts) {
|
|
|
1486
1490
|
warnings.push(`Custom domain provisioning returned: ${res.data?.error || "failed"}`);
|
|
1487
1491
|
}
|
|
1488
1492
|
} else {
|
|
1493
|
+
const freeBody = (s) => ({
|
|
1494
|
+
domainType: "free",
|
|
1495
|
+
slug: s,
|
|
1496
|
+
publicHost: d.publicHost,
|
|
1497
|
+
dashPort,
|
|
1498
|
+
localEdge: d.localEdge,
|
|
1499
|
+
edgeTakeover: d.edgeTakeover,
|
|
1500
|
+
edgeMigrate: d.edgeMigrate
|
|
1501
|
+
});
|
|
1489
1502
|
let slug = d.slug;
|
|
1490
|
-
let res = await internalPost(
|
|
1491
|
-
port,
|
|
1492
|
-
"/api/system/self-register",
|
|
1493
|
-
{ domainType: "free", slug, publicHost: d.publicHost, dashPort },
|
|
1494
|
-
token
|
|
1495
|
-
);
|
|
1503
|
+
let res = await internalPost(port, "/api/system/self-register", freeBody(slug), token);
|
|
1496
1504
|
for (let attempt = 0; !res.ok && isSlugTaken(res.data) && opts.onSlugTaken && attempt < 5; attempt++) {
|
|
1497
1505
|
const next = await opts.onSlugTaken(slug);
|
|
1498
1506
|
if (!next) break;
|
|
1499
1507
|
slug = next;
|
|
1500
|
-
res = await internalPost(
|
|
1501
|
-
port,
|
|
1502
|
-
"/api/system/self-register",
|
|
1503
|
-
{ domainType: "free", slug, publicHost: d.publicHost, dashPort },
|
|
1504
|
-
token
|
|
1505
|
-
);
|
|
1508
|
+
res = await internalPost(port, "/api/system/self-register", freeBody(slug), token);
|
|
1506
1509
|
}
|
|
1507
1510
|
domainRegistered = res.ok;
|
|
1508
1511
|
liveUrl = res.data?.url;
|
|
1512
|
+
if (res.ok && res.data?.sessionId) {
|
|
1513
|
+
const edge = await drainProvisionStream(port, String(res.data.sessionId), token, (m) => log6(` ${m}`));
|
|
1514
|
+
if (!edge.completed && edge.detail) {
|
|
1515
|
+
warnings.push(`Local edge not fully ready: ${edge.detail} \u2014 it retries on next boot.`);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1509
1518
|
if (!res.ok) {
|
|
1510
1519
|
warnings.push(
|
|
1511
1520
|
isSlugTaken(res.data) ? `Free domain not created: "${slug}.opsh.io" is already taken. Re-run and choose a different subdomain, or add one later in Settings \u2192 Domains.` : `Free .opsh.io domain not registered: ${res.data?.error || "failed"}. A free domain needs the box connected to Openship Cloud \u2014 connect it in Settings \u2192 Cloud, or use --domain-kind byo/custom.`
|
|
@@ -1526,6 +1535,12 @@ function normalizeUrl(raw) {
|
|
|
1526
1535
|
return null;
|
|
1527
1536
|
}
|
|
1528
1537
|
}
|
|
1538
|
+
function effectivePublicUrl(flag) {
|
|
1539
|
+
if (flag) return normalizePublicUrl(flag);
|
|
1540
|
+
const saved = readInstanceUrl();
|
|
1541
|
+
if (!saved || /^https?:\/\/(localhost|127\.|\[?::1\]?)([:/]|$)/i.test(saved)) return void 0;
|
|
1542
|
+
return normalizePublicUrl(saved);
|
|
1543
|
+
}
|
|
1529
1544
|
function normalizePublicUrl(raw) {
|
|
1530
1545
|
const url = normalizeUrl(raw);
|
|
1531
1546
|
if (!url) {
|
|
@@ -1541,7 +1556,7 @@ var DIST_DIR = dirname2(fileURLToPath(import.meta.url));
|
|
|
1541
1556
|
var SERVER_DIR = join8(DIST_DIR, "server");
|
|
1542
1557
|
function ensureAuthSecret() {
|
|
1543
1558
|
const path2 = join8(OS_DIR, "auth-secret");
|
|
1544
|
-
if (existsSync7(path2)) return
|
|
1559
|
+
if (existsSync7(path2)) return readFileSync5(path2, "utf8").trim();
|
|
1545
1560
|
mkdirSync8(OS_DIR, { recursive: true, mode: 448 });
|
|
1546
1561
|
const secret = randomBytes2(32).toString("hex");
|
|
1547
1562
|
writeFileSync7(path2, secret, { mode: 384 });
|
|
@@ -1683,7 +1698,7 @@ async function runCompose(opts) {
|
|
|
1683
1698
|
);
|
|
1684
1699
|
process.exit(1);
|
|
1685
1700
|
}
|
|
1686
|
-
const publicUrl =
|
|
1701
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1687
1702
|
const fromSource = sourceBuildDir();
|
|
1688
1703
|
const spinner5 = ora(
|
|
1689
1704
|
fromSource ? `Building Openship from ${fromSource} and starting the stack\u2026` : "Starting Openship via Docker Compose\u2026"
|
|
@@ -1693,8 +1708,10 @@ async function runCompose(opts) {
|
|
|
1693
1708
|
dashboardPort: opts.dashboardPort,
|
|
1694
1709
|
publicUrl,
|
|
1695
1710
|
trustProxy: opts.trustProxy,
|
|
1696
|
-
// commander maps `--no-host-control` to hostControl === false.
|
|
1697
|
-
|
|
1711
|
+
// commander maps `--no-host-control` to hostControl === false. `undefined` when
|
|
1712
|
+
// the flag is absent, so a plain re-run keeps the install's original choice
|
|
1713
|
+
// instead of silently re-granting host control (see resolveEnvConfig).
|
|
1714
|
+
noHostControl: opts.hostControl === false ? true : void 0
|
|
1698
1715
|
});
|
|
1699
1716
|
if (!res.ok) {
|
|
1700
1717
|
spinner5.fail("docker compose failed to start the stack");
|
|
@@ -1742,7 +1759,7 @@ async function runFromSource(opts) {
|
|
|
1742
1759
|
await runForeground(opts, src);
|
|
1743
1760
|
}
|
|
1744
1761
|
async function startService(opts, runOpts = {}) {
|
|
1745
|
-
const publicUrl =
|
|
1762
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1746
1763
|
if (opts.dryRun) {
|
|
1747
1764
|
const p = preview({
|
|
1748
1765
|
port: opts.port,
|
|
@@ -1841,7 +1858,7 @@ async function runForeground(opts, source) {
|
|
|
1841
1858
|
});
|
|
1842
1859
|
const port = String(resolved.api);
|
|
1843
1860
|
const dashPort = String(resolved.dashboard);
|
|
1844
|
-
const publicUrl =
|
|
1861
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1845
1862
|
const managedEdge = Boolean(opts.managedEdge && publicUrl);
|
|
1846
1863
|
const dataDir = opts.dataDir || join8(OS_DIR, "data");
|
|
1847
1864
|
mkdirSync8(dataDir, { recursive: true });
|
|
@@ -1863,9 +1880,12 @@ async function runForeground(opts, source) {
|
|
|
1863
1880
|
if (!source) {
|
|
1864
1881
|
env.OPENSHIP_MIGRATIONS_DIR = join8(SERVER_DIR, "migrations");
|
|
1865
1882
|
env.OPENSHIP_PGLITE_ASSETS_DIR = join8(SERVER_DIR, "pglite");
|
|
1883
|
+
const engineDir = join8(SERVER_DIR, "engine");
|
|
1884
|
+
if (existsSync7(engineDir)) env.MAIL_SERVER_ENGINE_DIR = engineDir;
|
|
1866
1885
|
}
|
|
1867
1886
|
env.OPENSHIP_REQUIRE_AUTH = "true";
|
|
1868
1887
|
env.INTERNAL_TOKEN = ensureInternalToken();
|
|
1888
|
+
if (!env.OPENSHIP_AUTH_MODE) env.OPENSHIP_AUTH_MODE = "local";
|
|
1869
1889
|
env.OPENSHIP_API_HOST = "127.0.0.1";
|
|
1870
1890
|
env.OPENSHIP_DASHBOARD_PORT = dashPort;
|
|
1871
1891
|
env.OPENSHIP_INSTANCE_LOG = instanceLogPath;
|
|
@@ -1953,7 +1973,7 @@ async function runForeground(opts, source) {
|
|
|
1953
1973
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1954
1974
|
try {
|
|
1955
1975
|
const bundle = await ensureDashboard({
|
|
1956
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.4.
|
|
1976
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.4.6"}`,
|
|
1957
1977
|
onProgress: (received, total) => {
|
|
1958
1978
|
if (total) {
|
|
1959
1979
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -2222,7 +2242,7 @@ var initCommand = new Command7("init").description("Link the current directory t
|
|
|
2222
2242
|
|
|
2223
2243
|
// src/commands/config.ts
|
|
2224
2244
|
import { Command as Command8 } from "commander";
|
|
2225
|
-
import { existsSync as existsSync10, readFileSync as
|
|
2245
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6, writeFileSync as writeFileSync9 } from "fs";
|
|
2226
2246
|
import { join as join10 } from "path";
|
|
2227
2247
|
var SCHEMA_URL = "https://openship.io/openship.schema.json";
|
|
2228
2248
|
var CONFIG_FILE = "openship.json";
|
|
@@ -2243,7 +2263,7 @@ function detectHints(dir) {
|
|
|
2243
2263
|
const pkgPath = join10(dir, "package.json");
|
|
2244
2264
|
if (existsSync10(pkgPath)) {
|
|
2245
2265
|
try {
|
|
2246
|
-
const pkg = JSON.parse(
|
|
2266
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
2247
2267
|
const runner = hints.packageManager ?? "npm";
|
|
2248
2268
|
const exec = runner === "npm" ? "npm run" : runner;
|
|
2249
2269
|
if (pkg.scripts?.build) hints.buildCommand = `${exec} build`;
|
|
@@ -2279,7 +2299,7 @@ var validateCmd = new Command8("validate").description("Validate an openship.jso
|
|
|
2279
2299
|
else err(`Not found: ${path2}`);
|
|
2280
2300
|
process.exit(1);
|
|
2281
2301
|
}
|
|
2282
|
-
const { config, errors, warnings } = parseOpenshipConfigJson(
|
|
2302
|
+
const { config, errors, warnings } = parseOpenshipConfigJson(readFileSync6(path2, "utf8"));
|
|
2283
2303
|
const valid = errors.length === 0 && config !== null;
|
|
2284
2304
|
if (isJsonMode()) {
|
|
2285
2305
|
printJson({ valid, errors, warnings });
|
|
@@ -2352,11 +2372,11 @@ var contextCommand = new Command9("context").alias("ctx").description("Manage co
|
|
|
2352
2372
|
// src/commands/status.ts
|
|
2353
2373
|
import { Command as Command10 } from "commander";
|
|
2354
2374
|
import chalk9 from "chalk";
|
|
2355
|
-
import { readFileSync as
|
|
2375
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
2356
2376
|
import { join as join11 } from "path";
|
|
2357
2377
|
function readPorts() {
|
|
2358
2378
|
try {
|
|
2359
|
-
return JSON.parse(
|
|
2379
|
+
return JSON.parse(readFileSync7(join11(OS_DIR, "ports.json"), "utf8"));
|
|
2360
2380
|
} catch {
|
|
2361
2381
|
return {};
|
|
2362
2382
|
}
|
|
@@ -2420,7 +2440,7 @@ import { intro, outro, note as note2, select as select3, log as log3, spinner as
|
|
|
2420
2440
|
|
|
2421
2441
|
// src/lib/repair.ts
|
|
2422
2442
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
2423
|
-
import { existsSync as existsSync12, readFileSync as
|
|
2443
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
|
|
2424
2444
|
import { join as join13 } from "path";
|
|
2425
2445
|
import chalk10 from "chalk";
|
|
2426
2446
|
import { spinner, log as log2, select as select2, isCancel as isCancel3, cancel } from "@clack/prompts";
|
|
@@ -2534,7 +2554,7 @@ function ensure(value) {
|
|
|
2534
2554
|
function storedPorts() {
|
|
2535
2555
|
try {
|
|
2536
2556
|
const p = join13(OS_DIR, "ports.json");
|
|
2537
|
-
return existsSync12(p) ? JSON.parse(
|
|
2557
|
+
return existsSync12(p) ? JSON.parse(readFileSync8(p, "utf8")) : {};
|
|
2538
2558
|
} catch {
|
|
2539
2559
|
return {};
|
|
2540
2560
|
}
|
|
@@ -2586,7 +2606,7 @@ function lastServiceError() {
|
|
|
2586
2606
|
const p = join13(LOG_DIR2, name);
|
|
2587
2607
|
if (!existsSync12(p)) continue;
|
|
2588
2608
|
try {
|
|
2589
|
-
const lines =
|
|
2609
|
+
const lines = readFileSync8(p, "utf8").trim().split("\n");
|
|
2590
2610
|
const hit = [...lines].reverse().find((l) => /error|locked|aborted|malformed|corrupt|throw|cannot|EADDRINUSE/i.test(l));
|
|
2591
2611
|
if (hit) return hit.trim().slice(0, 240);
|
|
2592
2612
|
} catch {
|
|
@@ -3013,7 +3033,7 @@ import { execFileSync as execFileSync4 } from "child_process";
|
|
|
3013
3033
|
import ora2 from "ora";
|
|
3014
3034
|
|
|
3015
3035
|
// src/lib/project-link.ts
|
|
3016
|
-
import { readFileSync as
|
|
3036
|
+
import { readFileSync as readFileSync9, existsSync as existsSync14 } from "fs";
|
|
3017
3037
|
import { join as join14, dirname as dirname3, parse } from "path";
|
|
3018
3038
|
var LINK_REL = join14(".openship", "project.json");
|
|
3019
3039
|
function findProjectLinkPath(from = process.cwd()) {
|
|
@@ -3030,7 +3050,7 @@ function readProjectLink(from) {
|
|
|
3030
3050
|
const path2 = findProjectLinkPath(from);
|
|
3031
3051
|
if (!path2) return null;
|
|
3032
3052
|
try {
|
|
3033
|
-
return JSON.parse(
|
|
3053
|
+
return JSON.parse(readFileSync9(path2, "utf8"));
|
|
3034
3054
|
} catch {
|
|
3035
3055
|
return null;
|
|
3036
3056
|
}
|
|
@@ -3038,7 +3058,7 @@ function readProjectLink(from) {
|
|
|
3038
3058
|
|
|
3039
3059
|
// src/lib/folder-deploy.ts
|
|
3040
3060
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
3041
|
-
import { readFileSync as
|
|
3061
|
+
import { readFileSync as readFileSync10, existsSync as existsSync15, rmSync as rmSync4 } from "fs";
|
|
3042
3062
|
import { tmpdir } from "os";
|
|
3043
3063
|
import { join as join15, basename } from "path";
|
|
3044
3064
|
function detectPackageManager(dir) {
|
|
@@ -3088,7 +3108,7 @@ async function deployFolder(opts) {
|
|
|
3088
3108
|
);
|
|
3089
3109
|
step("Uploading source");
|
|
3090
3110
|
try {
|
|
3091
|
-
const body =
|
|
3111
|
+
const body = readFileSync10(tarball);
|
|
3092
3112
|
const up = session.upload;
|
|
3093
3113
|
const method = up.method || "POST";
|
|
3094
3114
|
const res = /^https?:\/\//i.test(up.url) ? await fetch(up.url, { method, headers: up.headers, body }) : await apiRaw(`/${up.url.replace(/^\/+/, "")}`, { method, headers: up.headers, body });
|
|
@@ -4800,7 +4820,7 @@ var domainCommand = new Command17("domain").description("Manage custom domains,
|
|
|
4800
4820
|
import { Command as Command18 } from "commander";
|
|
4801
4821
|
import chalk15 from "chalk";
|
|
4802
4822
|
import ora4 from "ora";
|
|
4803
|
-
var INSTALLABLE = ["docker", "git", "
|
|
4823
|
+
var INSTALLABLE = ["docker", "git", "edge", "rsync"];
|
|
4804
4824
|
function guard(fn) {
|
|
4805
4825
|
return async (...args) => {
|
|
4806
4826
|
if (!getToken()) {
|
|
@@ -5094,7 +5114,7 @@ var serverCommand = server;
|
|
|
5094
5114
|
// src/commands/system.ts
|
|
5095
5115
|
import { Command as Command19 } from "commander";
|
|
5096
5116
|
import ora5 from "ora";
|
|
5097
|
-
import { readFileSync as
|
|
5117
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
5098
5118
|
import { createInterface as createInterface6 } from "readline/promises";
|
|
5099
5119
|
import { stdin as input5, stdout as output5 } from "process";
|
|
5100
5120
|
async function guarded(fn) {
|
|
@@ -5420,7 +5440,7 @@ dataTransferCommand.command("import").description("Import an instance export fil
|
|
|
5420
5440
|
}
|
|
5421
5441
|
let file;
|
|
5422
5442
|
try {
|
|
5423
|
-
file = JSON.parse(
|
|
5443
|
+
file = JSON.parse(readFileSync11(opts.file, "utf8"));
|
|
5424
5444
|
} catch {
|
|
5425
5445
|
err(`
|
|
5426
5446
|
Could not read or parse ${opts.file}.
|
|
@@ -5771,7 +5791,7 @@ var mailCommand = new Command20("mail").description("Self-hosted mail server (iR
|
|
|
5771
5791
|
// src/commands/backup.ts
|
|
5772
5792
|
import { Command as Command21 } from "commander";
|
|
5773
5793
|
import ora7 from "ora";
|
|
5774
|
-
import { readFileSync as
|
|
5794
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
5775
5795
|
async function guard3(fn) {
|
|
5776
5796
|
try {
|
|
5777
5797
|
await fn();
|
|
@@ -6064,7 +6084,7 @@ destinationCmd.command("create").description("Create a backup destination").requ
|
|
|
6064
6084
|
let sftpPrivateKey = opts.sftpPrivateKey;
|
|
6065
6085
|
if (opts.sftpPrivateKeyFile) {
|
|
6066
6086
|
try {
|
|
6067
|
-
sftpPrivateKey =
|
|
6087
|
+
sftpPrivateKey = readFileSync12(opts.sftpPrivateKeyFile, "utf8");
|
|
6068
6088
|
} catch {
|
|
6069
6089
|
throw new Error(`Cannot read key file: ${opts.sftpPrivateKeyFile}`);
|
|
6070
6090
|
}
|
|
@@ -6256,11 +6276,11 @@ var apiCommand = new Command23("api").description("Make an authenticated request
|
|
|
6256
6276
|
import { Command as Command24 } from "commander";
|
|
6257
6277
|
import chalk19 from "chalk";
|
|
6258
6278
|
import { intro as intro2, outro as outro2, password as passwordPrompt, isCancel as isCancel4, cancel as cancel3, log as log4 } from "@clack/prompts";
|
|
6259
|
-
import { readFileSync as
|
|
6279
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
6260
6280
|
import { join as join16 } from "path";
|
|
6261
6281
|
function resolvedApiPort() {
|
|
6262
6282
|
try {
|
|
6263
|
-
return JSON.parse(
|
|
6283
|
+
return JSON.parse(readFileSync13(join16(OS_DIR, "ports.json"), "utf8")).api;
|
|
6264
6284
|
} catch {
|
|
6265
6285
|
return void 0;
|
|
6266
6286
|
}
|
|
@@ -6314,7 +6334,7 @@ var resetAdminCommand = new Command24("reset-admin-password").description("Reset
|
|
|
6314
6334
|
|
|
6315
6335
|
// src/commands/install.ts
|
|
6316
6336
|
import { Command as Command25 } from "commander";
|
|
6317
|
-
import { chmodSync as chmodSync2, existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as
|
|
6337
|
+
import { chmodSync as chmodSync2, existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "fs";
|
|
6318
6338
|
import { spawn as spawn2, spawnSync as spawnSync6 } from "child_process";
|
|
6319
6339
|
import { homedir as homedir3 } from "os";
|
|
6320
6340
|
import { join as join17 } from "path";
|
|
@@ -6451,7 +6471,7 @@ var installCommand = new Command25("install").description("Download and install
|
|
|
6451
6471
|
try {
|
|
6452
6472
|
let sidecarBody;
|
|
6453
6473
|
if (existsSync16(sidecarPath) && !downloaded) {
|
|
6454
|
-
sidecarBody =
|
|
6474
|
+
sidecarBody = readFileSync14(sidecarPath, "utf8");
|
|
6455
6475
|
} else {
|
|
6456
6476
|
sidecarBody = await fetchSidecar(sidecarUrl);
|
|
6457
6477
|
}
|
|
@@ -6562,7 +6582,7 @@ function detectPackageManager2(override) {
|
|
|
6562
6582
|
var updateCommand = new Command26("update").description("Update the Openship CLI + bundled server to the latest release").option("--check", "Only report the current + latest version; don't install").option("--via <manager>", "Package manager to update with: bun | npm").option("--rebuild", "From-source installs: rebuild even if already at the remote tip").action(async (opts) => {
|
|
6563
6583
|
const source = readSourceInstall();
|
|
6564
6584
|
if (source) return runSourceUpdate(source, opts);
|
|
6565
|
-
const current = "0.4.
|
|
6585
|
+
const current = "0.4.6";
|
|
6566
6586
|
let latest;
|
|
6567
6587
|
try {
|
|
6568
6588
|
latest = (await resolveLatestTag()).replace(/^v/, "");
|
|
@@ -6597,13 +6617,13 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
|
|
|
6597
6617
|
return;
|
|
6598
6618
|
}
|
|
6599
6619
|
if (readInstallMethod() === "compose") {
|
|
6600
|
-
const
|
|
6620
|
+
const applied = composeUpdate(latest);
|
|
6601
6621
|
if (isJsonMode()) {
|
|
6602
|
-
printJson({ updated: true, from: current, to: latest, via: pm, method: "compose",
|
|
6603
|
-
} else if (
|
|
6604
|
-
ok(`Updated to v${latest}
|
|
6622
|
+
printJson({ updated: true, from: current, to: latest, via: pm, method: "compose", applied });
|
|
6623
|
+
} else if (applied) {
|
|
6624
|
+
ok(`Updated to v${latest} \u2014 compose stack regenerated, images pulled, services recreated.`);
|
|
6605
6625
|
} else {
|
|
6606
|
-
err(`Updated the CLI to v${latest}, but
|
|
6626
|
+
err(`Updated the CLI to v${latest}, but bringing the compose stack up failed. Re-run \`openship update\`, or \`openship up\` to retry.`);
|
|
6607
6627
|
process.exitCode = 1;
|
|
6608
6628
|
}
|
|
6609
6629
|
return;
|
|
@@ -6620,7 +6640,7 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
|
|
|
6620
6640
|
|
|
6621
6641
|
// src/commands/cache.ts
|
|
6622
6642
|
import { Command as Command27 } from "commander";
|
|
6623
|
-
import { existsSync as existsSync17, readdirSync as readdirSync2, readFileSync as
|
|
6643
|
+
import { existsSync as existsSync17, readdirSync as readdirSync2, readFileSync as readFileSync15, rmSync as rmSync5, statSync as statSync2 } from "fs";
|
|
6624
6644
|
import { join as join18 } from "path";
|
|
6625
6645
|
function listAssets() {
|
|
6626
6646
|
if (!existsSync17(RELEASES_DIR)) return [];
|
|
@@ -6669,7 +6689,7 @@ var verifyCmd2 = new Command27("verify").description("Re-hash cached assets and
|
|
|
6669
6689
|
results.push({ tag: a.tag, asset: a.name, result: "no-sidecar" });
|
|
6670
6690
|
continue;
|
|
6671
6691
|
}
|
|
6672
|
-
const expected = parseSha256(
|
|
6692
|
+
const expected = parseSha256(readFileSync15(`${a.path}.sha256`, "utf8"));
|
|
6673
6693
|
const actual = await hashFile(a.path);
|
|
6674
6694
|
const okMatch = expected !== null && expected === actual;
|
|
6675
6695
|
if (!okMatch) bad += 1;
|
|
@@ -6705,7 +6725,7 @@ var cacheCommand = new Command27("cache").description("Manage the local download
|
|
|
6705
6725
|
import chalk20 from "chalk";
|
|
6706
6726
|
import open2 from "open";
|
|
6707
6727
|
import { createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
|
|
6708
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync12, readFileSync as
|
|
6728
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync12, readFileSync as readFileSync16, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
6709
6729
|
import { join as join19 } from "path";
|
|
6710
6730
|
import {
|
|
6711
6731
|
intro as intro3,
|
|
@@ -6893,6 +6913,21 @@ ${pad("Login")}${opts.adminEmail} ${chalk20.dim("(email + password you set)")}
|
|
|
6893
6913
|
);
|
|
6894
6914
|
outro3(opts.byo ? chalk20.dim("Point your reverse proxy at the dashboard port above.") : chalk20.green("Happy shipping."));
|
|
6895
6915
|
}
|
|
6916
|
+
async function promptLocalEdgeTakeover(port) {
|
|
6917
|
+
const pf = await internalPost(port, "/api/system/self-edge/preflight", {});
|
|
6918
|
+
const status = pf.ok ? pf.data?.status : void 0;
|
|
6919
|
+
if (!status || status.canProceedClean || !status.occupants?.length) {
|
|
6920
|
+
return { proceed: true, edgeMigrate: false, edgeTakeover: false };
|
|
6921
|
+
}
|
|
6922
|
+
const owner = status.occupants.map((o) => o.command ?? `port ${o.port}`).join(", ");
|
|
6923
|
+
const known = status.classification === "known";
|
|
6924
|
+
const sites = pf.ok && Array.isArray(pf.data?.sites) ? pf.data.sites : [];
|
|
6925
|
+
const warnings = pf.ok && Array.isArray(pf.data?.warnings) ? pf.data.warnings : [];
|
|
6926
|
+
renderEdgeConflict({ owner, sites, warnings });
|
|
6927
|
+
const action2 = await confirmEdgeAction({ owner, known, importable: sites.length });
|
|
6928
|
+
if (action2 === "cancel") return { proceed: false, edgeMigrate: false, edgeTakeover: false };
|
|
6929
|
+
return { proceed: true, edgeMigrate: action2 === "migrate", edgeTakeover: action2 === "takeover" };
|
|
6930
|
+
}
|
|
6896
6931
|
async function runWizard() {
|
|
6897
6932
|
const resuming = isSetupInProgress();
|
|
6898
6933
|
intro3(`${chalk20.bgCyan(chalk20.black(" Openship "))}${chalk20.dim(" setup")}`);
|
|
@@ -7114,7 +7149,7 @@ async function runWizard() {
|
|
|
7114
7149
|
}
|
|
7115
7150
|
}
|
|
7116
7151
|
}
|
|
7117
|
-
const uiTag = `v${"0.4.
|
|
7152
|
+
const uiTag = `v${"0.4.6"}`;
|
|
7118
7153
|
if (method === "bare") {
|
|
7119
7154
|
const dl = spinner4();
|
|
7120
7155
|
dl.start("Pulling the Openship dist from GitHub");
|
|
@@ -7182,7 +7217,7 @@ async function runWizard() {
|
|
|
7182
7217
|
const up = composeUp({
|
|
7183
7218
|
publicUrl,
|
|
7184
7219
|
trustProxy: behindProxy,
|
|
7185
|
-
version: "0.4.
|
|
7220
|
+
version: "0.4.6",
|
|
7186
7221
|
noHostControl: !allowHostControl
|
|
7187
7222
|
});
|
|
7188
7223
|
if (!up.ok) {
|
|
@@ -7319,93 +7354,49 @@ async function runWizard() {
|
|
|
7319
7354
|
await internalPost(port, "/api/system/self-register", { domainType: "byo" });
|
|
7320
7355
|
} else {
|
|
7321
7356
|
cloudEmail = cloud.email;
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
const res = await internalPost(port, "/api/system/self-register", {
|
|
7327
|
-
domainType: "free",
|
|
7328
|
-
slug: regSlug,
|
|
7329
|
-
publicHost: domainPlan.publicHost,
|
|
7330
|
-
dashPort: Number(started.dashPort)
|
|
7331
|
-
});
|
|
7332
|
-
if (res.ok && res.data?.url) {
|
|
7333
|
-
liveUrl = res.data.url;
|
|
7334
|
-
s2.stop(`Free domain live: ${res.data.url}`);
|
|
7335
|
-
break;
|
|
7336
|
-
}
|
|
7337
|
-
s2.stop(`Couldn't register ${regSlug}.opsh.io: ${res.data?.error || "failed"}`, 1);
|
|
7338
|
-
const next = ensure2(
|
|
7339
|
-
await select4({
|
|
7340
|
-
message: "Try a different subdomain?",
|
|
7341
|
-
options: [
|
|
7342
|
-
{ value: "retry", label: "Pick another subdomain" },
|
|
7343
|
-
{ value: "skip", label: "Skip for now", hint: "log in on this server; add a domain later in Settings \u2192 Cloud" }
|
|
7344
|
-
]
|
|
7345
|
-
})
|
|
7357
|
+
const edge = await promptLocalEdgeTakeover(port);
|
|
7358
|
+
if (!edge.proceed) {
|
|
7359
|
+
log5.warn(
|
|
7360
|
+
"Left the existing proxy on 80/443 running \u2014 a free domain forwards to :80 here, so it won't serve until Openship owns that port. Re-run setup and choose migrate / take over."
|
|
7346
7361
|
);
|
|
7347
|
-
if (next === "skip") break;
|
|
7348
|
-
regSlug = ensure2(
|
|
7349
|
-
await text({
|
|
7350
|
-
message: "Choose your subdomain",
|
|
7351
|
-
placeholder: "my-openship",
|
|
7352
|
-
initialValue: regSlug,
|
|
7353
|
-
validate: (v) => v && SLUG_RE2.test(v.trim().toLowerCase()) ? void 0 : "Lowercase letters, digits, hyphens"
|
|
7354
|
-
})
|
|
7355
|
-
).trim().toLowerCase();
|
|
7356
7362
|
}
|
|
7363
|
+
const result = await headlessProvision({
|
|
7364
|
+
port,
|
|
7365
|
+
dashPort: started.dashPort,
|
|
7366
|
+
token: provisionToken,
|
|
7367
|
+
method: "bare",
|
|
7368
|
+
inputs: {
|
|
7369
|
+
admin,
|
|
7370
|
+
domain: {
|
|
7371
|
+
kind: "free",
|
|
7372
|
+
slug: domainPlan.slug,
|
|
7373
|
+
publicHost: domainPlan.publicHost,
|
|
7374
|
+
// Bare needs a local :80 edge for Cloud to forward to; skip only when
|
|
7375
|
+
// the operator declined the takeover (their proxy keeps 80/443).
|
|
7376
|
+
localEdge: edge.proceed,
|
|
7377
|
+
edgeTakeover: edge.edgeTakeover,
|
|
7378
|
+
edgeMigrate: edge.edgeMigrate
|
|
7379
|
+
}
|
|
7380
|
+
},
|
|
7381
|
+
onLog: (msg) => log5.message(chalk20.dim(msg)),
|
|
7382
|
+
onSlugTaken: async (taken) => {
|
|
7383
|
+
log5.warn(`"${taken}.opsh.io" is already taken.`);
|
|
7384
|
+
const next = await text({
|
|
7385
|
+
message: "Choose a different subdomain (or leave empty to skip the free domain)",
|
|
7386
|
+
placeholder: "my-openship",
|
|
7387
|
+
validate: (v) => !v || SLUG_RE2.test(v.trim().toLowerCase()) ? void 0 : "Lowercase letters, digits, hyphens"
|
|
7388
|
+
});
|
|
7389
|
+
return isCancel5(next) || !next.trim() ? null : next.trim().toLowerCase();
|
|
7390
|
+
}
|
|
7391
|
+
});
|
|
7392
|
+
if (result.liveUrl) liveUrl = result.liveUrl;
|
|
7393
|
+
for (const w of result.warnings) log5.warn(w);
|
|
7357
7394
|
}
|
|
7358
7395
|
} else if (domainPlan.type === "custom") {
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
const
|
|
7363
|
-
const status = pf.ok ? pf.data?.status : void 0;
|
|
7364
|
-
const importable = pf.ok && Array.isArray(pf.data?.sites) ? pf.data.sites.length : 0;
|
|
7365
|
-
if (status && !status.canProceedClean && status.occupants?.length) {
|
|
7366
|
-
const owner = status.occupants.map((o) => o.command ?? `port ${o.port}`).join(", ");
|
|
7367
|
-
const known = status.classification === "known";
|
|
7368
|
-
const sites = pf.ok && Array.isArray(pf.data?.sites) ? pf.data.sites : [];
|
|
7369
|
-
if (sites.length > 0) {
|
|
7370
|
-
const lines = sites.map((st) => {
|
|
7371
|
-
const host = (st.serverNames ?? []).join(", ") || "(no server_name)";
|
|
7372
|
-
const dest = st.target?.kind === "static" ? `static: ${st.target?.root ?? ""}` : st.target?.url ?? "";
|
|
7373
|
-
return `${chalk20.bold(host)} \u2192 ${chalk20.dim(dest)}${st.ssl ? chalk20.green(" [TLS]") : ""}`;
|
|
7374
|
-
});
|
|
7375
|
-
note3(lines.join("\n"), `Detected ${sites.length} site${sites.length === 1 ? "" : "s"} on ${owner}`);
|
|
7376
|
-
}
|
|
7377
|
-
const warns = pf.ok && Array.isArray(pf.data?.warnings) ? pf.data.warnings : [];
|
|
7378
|
-
if (warns.length > 0) {
|
|
7379
|
-
log5.warn(`${warns.length} config item${warns.length === 1 ? "" : "s"} won't migrate automatically:`);
|
|
7380
|
-
for (const w of warns.slice(0, 8)) log5.message(chalk20.dim(`\u2022 ${w}`));
|
|
7381
|
-
}
|
|
7382
|
-
const choice = ensure2(
|
|
7383
|
-
await select4({
|
|
7384
|
-
message: known ? `An existing reverse proxy (${owner}) is serving ports 80/443.` : `Ports 80/443 are in use by ${owner}, which we couldn't identify.`,
|
|
7385
|
-
options: [
|
|
7386
|
-
...importable > 0 ? [{
|
|
7387
|
-
value: "migrate",
|
|
7388
|
-
label: `Migrate ${importable} site${importable === 1 ? "" : "s"} & take over`,
|
|
7389
|
-
hint: "import the existing sites into Openship, then take 80/443"
|
|
7390
|
-
}] : [],
|
|
7391
|
-
{
|
|
7392
|
-
value: "override",
|
|
7393
|
-
label: "Stop it & take over 80/443",
|
|
7394
|
-
hint: known ? "the existing sites stop being served" : "may interrupt a running service"
|
|
7395
|
-
},
|
|
7396
|
-
{ value: "cancel", label: "Cancel \u2014 leave it running" }
|
|
7397
|
-
],
|
|
7398
|
-
// Same default as the `up` preflight (edge-preflight.ts): migrate when
|
|
7399
|
-
// there are importable sites — it takes 80/443 without dropping any of
|
|
7400
|
-
// them. Otherwise a known proxy defaults to cancel (Enter must not stop
|
|
7401
|
-
// sites that are being served) and an unidentified holder to takeover.
|
|
7402
|
-
initialValue: importable > 0 ? "migrate" : known ? "cancel" : "override"
|
|
7403
|
-
})
|
|
7404
|
-
);
|
|
7405
|
-
if (choice === "cancel") proceedCustom = false;
|
|
7406
|
-
else if (choice === "migrate") edgeMigrate = true;
|
|
7407
|
-
else edgeTakeover = true;
|
|
7408
|
-
}
|
|
7396
|
+
const edge = await promptLocalEdgeTakeover(port);
|
|
7397
|
+
const proceedCustom = edge.proceed;
|
|
7398
|
+
const edgeTakeover = edge.edgeTakeover;
|
|
7399
|
+
const edgeMigrate = edge.edgeMigrate;
|
|
7409
7400
|
if (!proceedCustom) {
|
|
7410
7401
|
log5.warn(
|
|
7411
7402
|
"Left the existing proxy on 80/443 running. Registering Openship without managed HTTPS \u2014 front it with your proxy, or re-run setup to take over."
|
|
@@ -7460,13 +7451,16 @@ async function runWizard() {
|
|
|
7460
7451
|
function storedPorts2() {
|
|
7461
7452
|
const p = join19(OS_DIR, "ports.json");
|
|
7462
7453
|
try {
|
|
7463
|
-
return existsSync18(p) ? JSON.parse(
|
|
7454
|
+
return existsSync18(p) ? JSON.parse(readFileSync16(p, "utf8")) : {};
|
|
7464
7455
|
} catch {
|
|
7465
7456
|
return {};
|
|
7466
7457
|
}
|
|
7467
7458
|
}
|
|
7468
7459
|
async function runControl() {
|
|
7469
7460
|
const svc = serviceStatus();
|
|
7461
|
+
const isCompose = readInstallMethod() === "compose";
|
|
7462
|
+
const running = isCompose ? composeRunning() : svc.running;
|
|
7463
|
+
const managerLabel = isCompose ? "docker compose" : svc.kind === "unsupported" ? "none" : svc.kind;
|
|
7470
7464
|
const ports = storedPorts2();
|
|
7471
7465
|
const apiPort2 = String(ports.api ?? 4e3);
|
|
7472
7466
|
const dashUrl = `http://localhost:${ports.dashboard ?? 3001}`;
|
|
@@ -7475,10 +7469,10 @@ async function runControl() {
|
|
|
7475
7469
|
intro3(`${chalk20.bgCyan(chalk20.black(" Openship "))}${chalk20.dim(" control")}`);
|
|
7476
7470
|
note3(
|
|
7477
7471
|
`${chalk20.dim("URL".padEnd(11))}${chalk20.bold(primaryUrl)}
|
|
7478
|
-
${chalk20.dim("Service".padEnd(11))}${
|
|
7472
|
+
${chalk20.dim("Service".padEnd(11))}${running ? chalk20.green("running") : chalk20.yellow("stopped")}
|
|
7479
7473
|
${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
7480
7474
|
` + (ports.api ? `${chalk20.dim("API".padEnd(11))}http://localhost:${ports.api}
|
|
7481
|
-
` : "") + `${chalk20.dim("Manager".padEnd(11))}${
|
|
7475
|
+
` : "") + `${chalk20.dim("Manager".padEnd(11))}${managerLabel}`,
|
|
7482
7476
|
"Openship is already set up"
|
|
7483
7477
|
);
|
|
7484
7478
|
const corrupted = looksCorrupted();
|
|
@@ -7491,7 +7485,7 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7491
7485
|
options: [
|
|
7492
7486
|
...corrupted ? [{ value: "repair", label: "Repair database", hint: "backup \u2192 heal \u2192 verify" }] : [],
|
|
7493
7487
|
{ value: "open", label: "Open the dashboard" },
|
|
7494
|
-
|
|
7488
|
+
running ? { value: "restart", label: "Restart the service" } : { value: "start", label: "Start the service" },
|
|
7495
7489
|
{ value: "stop", label: "Stop the service", hint: "won't restart on boot" },
|
|
7496
7490
|
...corrupted ? [] : [{ value: "repair", label: "Repair database", hint: "backup \u2192 heal a corrupt DB" }],
|
|
7497
7491
|
{ value: "reset", label: "Reset admin password", hint: "sets a local email + password login" },
|
|
@@ -7511,15 +7505,31 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7511
7505
|
});
|
|
7512
7506
|
outro3(chalk20.dim(`Opening ${primaryUrl}`));
|
|
7513
7507
|
return;
|
|
7514
|
-
case "start":
|
|
7508
|
+
case "start": {
|
|
7509
|
+
if (isCompose) {
|
|
7510
|
+
const ok3 = composeStart();
|
|
7511
|
+
outro3(ok3 ? chalk20.green("Started.") : chalk20.yellow("Couldn't start the stack \u2014 run `openship up` to see the error."));
|
|
7512
|
+
return;
|
|
7513
|
+
}
|
|
7515
7514
|
await startService({});
|
|
7516
7515
|
return;
|
|
7516
|
+
}
|
|
7517
7517
|
case "restart": {
|
|
7518
|
+
if (isCompose) {
|
|
7519
|
+
const ok3 = composeRestart();
|
|
7520
|
+
outro3(ok3 ? chalk20.green("Restarted.") : chalk20.yellow("Couldn't restart the stack."));
|
|
7521
|
+
return;
|
|
7522
|
+
}
|
|
7518
7523
|
const r = restart();
|
|
7519
7524
|
outro3(r.restarted ? chalk20.green("Restarted.") : chalk20.yellow(r.detail));
|
|
7520
7525
|
return;
|
|
7521
7526
|
}
|
|
7522
7527
|
case "stop": {
|
|
7528
|
+
if (isCompose) {
|
|
7529
|
+
const ok3 = composeDown();
|
|
7530
|
+
outro3(ok3 ? chalk20.green("Stopped. Won't restart on boot.") : chalk20.yellow("Couldn't stop the stack."));
|
|
7531
|
+
return;
|
|
7532
|
+
}
|
|
7523
7533
|
const r = stop();
|
|
7524
7534
|
outro3(chalk20.green(`Stopped. ${chalk20.dim(r.detail)}`));
|
|
7525
7535
|
return;
|
|
@@ -7544,10 +7554,11 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7544
7554
|
|
|
7545
7555
|
// src/index.ts
|
|
7546
7556
|
var program = new Command28();
|
|
7547
|
-
program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.
|
|
7557
|
+
program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.6").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
|
|
7548
7558
|
if (thisCommand.opts().json) setJsonMode(true);
|
|
7549
7559
|
}).action(async () => {
|
|
7550
|
-
|
|
7560
|
+
const installed = serviceStatus().installed || readInstallMethod() === "compose";
|
|
7561
|
+
if (installed && !isSetupInProgress()) await runControl();
|
|
7551
7562
|
else await runWizard();
|
|
7552
7563
|
});
|
|
7553
7564
|
program.addCommand(upCommand);
|