openship 0.4.4 → 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-MFQA6OS4.js → bowser-O3AEA6AN.js} +5 -1
- package/dist/{chunk-KD7VO4LG.js → chunk-2ZLR7ULL.js} +255 -65
- package/dist/{chunk-YHXCHW7Q.js → chunk-3JQTL4R4.js} +236 -99
- package/dist/{chunk-E77LJWJK.js → chunk-4TJC4JZQ.js} +20 -9
- package/dist/{chunk-YL67EWYZ.js → chunk-4Z5QO7N6.js} +6 -2
- package/dist/{chunk-WJPCBU7Z.js → chunk-5FNIWBFI.js} +10 -6
- package/dist/{chunk-Y37KHU7L.js → chunk-5MZ624VX.js} +5 -0
- package/dist/{chunk-QKFRZNKN.js → chunk-6APIPIJY.js} +8 -4
- package/dist/{chunk-JZLNHGLW.js → chunk-6APULWSU.js} +153 -133
- package/dist/{chunk-F4DFVG6Q.js → chunk-6B5YCFFV.js} +8 -4
- package/dist/{chunk-XVSAUO2I.js → chunk-AVIB7CT7.js} +5 -1
- package/dist/{chunk-TEYJYSMT.js → chunk-C5OHTYEF.js} +12 -6
- package/dist/{chunk-7UOB5GGQ.js → chunk-DYPH4HCI.js} +5 -0
- package/dist/{chunk-XIFRMKYT.js → chunk-EI575GHN.js} +6 -2
- package/dist/{chunk-4CQWT2WL.js → chunk-FPRHYBY2.js} +5 -0
- package/dist/chunk-FQGJZ2HS.js +248 -0
- package/dist/{chunk-JR2OCMJA.js → chunk-FRNAR33O.js} +6 -2
- package/dist/{chunk-JUJBBF5U.js → chunk-FXTBHTWY.js} +362 -42
- package/dist/chunk-ILFETZOM.js +131 -0
- package/dist/{chunk-5ZCKQ2MI.js → chunk-IXCHURVK.js} +7 -3
- package/dist/{chunk-6ERIMTBC.js → chunk-JYGD5WSN.js} +5 -0
- package/dist/{chunk-4VNS5WPM.js → chunk-KI2EY3WB.js} +4 -0
- package/dist/{chunk-3U4SPZD5.js → chunk-L2VOGB2X.js} +7 -104
- package/dist/{chunk-NB2VEIWG.js → chunk-MZ2WEHHY.js} +7 -3
- package/dist/{chunk-BUBSSKO6.js → chunk-O6ZZF52V.js} +5 -1
- package/dist/{chunk-LBFH7THC.js → chunk-OWED2GRM.js} +5 -1
- package/dist/{chunk-4MG3BVHE.js → chunk-OXWDY22G.js} +6 -2
- package/dist/{chunk-4FABQGQP.js → chunk-Q2CIRAOK.js} +5 -0
- package/dist/{chunk-4LEL3H2Z.js → chunk-RPHRPFEH.js} +5 -0
- package/dist/{chunk-46YJFP4S.js → chunk-SQ77DZOI.js} +1728 -1484
- package/dist/{chunk-S6DSRLNE.js → chunk-TGIINPVM.js} +15 -2
- package/dist/{chunk-U2DPZSXA.js → chunk-TYVME3XD.js} +9 -1
- package/dist/{chunk-HFYDYK4D.js → chunk-V6AN6XLZ.js} +18 -6
- package/dist/{chunk-ZKJOFWBJ.js → chunk-VDMQJHPI.js} +38 -15
- package/dist/{chunk-E6W2JMMU.js → chunk-VFINNTUL.js} +22 -1
- package/dist/{chunk-OJE6YWPQ.js → chunk-VWPEKOH6.js} +6 -2
- package/dist/{chunk-5N7VUGL6.js → chunk-W73X43R7.js} +6 -2
- package/dist/cloud-7QYOGF7F.js +11 -0
- package/dist/cloud-ZSKOS4GY.js +30 -0
- package/dist/detect-SH4FHFBI.js +36 -0
- package/dist/{dist-L3MPOWCA.js → dist-IQJ6H6UZ.js} +6 -2
- package/dist/{dist-es-KE56MWYO.js → dist-es-5DY7K32L.js} +9 -5
- package/dist/dist-es-JSTDUS7Q.js +26 -0
- package/dist/{dist-es-GTAMF674.js → dist-es-OSNJBLXB.js} +8 -4
- package/dist/{dist-es-NRZIQY5B.js → dist-es-RYHIPOTN.js} +17 -13
- package/dist/{dist-es-XQCOTGC7.js → dist-es-VNKHQVIB.js} +7 -3
- package/dist/{dist-es-WZCR7DHQ.js → dist-es-WV4AMOII.js} +11 -7
- package/dist/{dist-es-ZW3HFQUM.js → dist-es-X3B5QYKB.js} +9 -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-7LGDL56D.js → event-streams-EHRAKL75.js} +7 -3
- package/dist/executor-YPT6RH6O.js +30 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +258 -245
- package/dist/{loadSso-N273C5I7.js → loadSso-46FQRIZS.js} +13 -9
- package/dist/local-executor-V7U5VOZW.js +12 -0
- package/dist/nginx-2GTRUIDE.js +24 -0
- package/dist/noop-FMMFG2EZ.js +11 -0
- package/dist/{openresty-lua-HAO4EUDY.js → openresty-lua-4WLGDSER.js} +13 -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-DR462ERO.js → signin-ITOPKKUB.js} +13 -9
- package/dist/{sso-oidc-VBZLJUK5.js → sso-oidc-NON2PD7Y.js} +13 -9
- package/dist/{sts-EJLZ4Z77.js → sts-HHFFSAY2.js} +12 -8
- package/package.json +1 -1
- package/dist/bare-ITM45QBX.js +0 -18
- package/dist/cloud-JMPHO3CW.js +0 -7
- package/dist/cloud-W5G6YXAY.js +0 -24
- package/dist/dist-es-4C322O5D.js +0 -22
- package/dist/docker-3FVJMFC3.js +0 -12
- package/dist/docker-edge-executor-ZIWAZWPL.js +0 -9
- package/dist/edge-import-Y34YL6JK.js +0 -39
- package/dist/executor-J7BHW5HF.js +0 -26
- package/dist/nginx-YZWKYKQU.js +0 -16
- package/dist/noop-RRNCIUI5.js +0 -7
- package/dist/setup-5X3WEEHA.js +0 -14
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
|
|
3
|
+
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
|
+
const require = __ospCreateRequire(import.meta.url);
|
|
2
5
|
import {
|
|
3
6
|
IS_ALT_HOME,
|
|
4
7
|
OS_DIR,
|
|
@@ -6,6 +9,9 @@ import {
|
|
|
6
9
|
composeInternalToken,
|
|
7
10
|
composeIsViableDefault,
|
|
8
11
|
composePs,
|
|
12
|
+
composeRestart,
|
|
13
|
+
composeRunning,
|
|
14
|
+
composeStart,
|
|
9
15
|
composeUninstall,
|
|
10
16
|
composeUp,
|
|
11
17
|
composeUpdate,
|
|
@@ -19,47 +25,54 @@ import {
|
|
|
19
25
|
remoteSha,
|
|
20
26
|
shortSha,
|
|
21
27
|
sourceBuildDir
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./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-KD7VO4LG.js";
|
|
37
|
-
import "./chunk-ZKJOFWBJ.js";
|
|
38
|
-
import "./chunk-WJPCBU7Z.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";
|
|
39
42
|
import {
|
|
40
43
|
beginEdgeTakeover,
|
|
44
|
+
collectProxyCerts,
|
|
41
45
|
completeEdgeTakeover,
|
|
42
46
|
detectInstalledProxy,
|
|
47
|
+
edgeProxy,
|
|
48
|
+
edgeProxyFor,
|
|
43
49
|
foreignProxyOnEdge,
|
|
44
50
|
importSites,
|
|
45
|
-
ourEdgeContainerRunning,
|
|
46
51
|
recoverInterruptedTakeover,
|
|
47
52
|
rollbackEdgeTakeover,
|
|
48
53
|
scanImportableSites
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import "./chunk-
|
|
51
|
-
import "./chunk-
|
|
52
|
-
import "./chunk-
|
|
53
|
-
import "./chunk-
|
|
54
|
-
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";
|
|
55
66
|
import {
|
|
56
67
|
LocalExecutor
|
|
57
|
-
} from "./chunk-
|
|
58
|
-
import "./chunk-
|
|
59
|
-
import "./chunk-
|
|
60
|
-
import
|
|
61
|
-
|
|
62
|
-
|
|
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";
|
|
63
76
|
import {
|
|
64
77
|
CLOUD_DASHBOARD_URL,
|
|
65
78
|
LOCAL_API_URL,
|
|
@@ -68,9 +81,8 @@ import {
|
|
|
68
81
|
isValidEmail,
|
|
69
82
|
parseOpenshipConfigJson,
|
|
70
83
|
resolveCliUpdatePlan
|
|
71
|
-
} from "./chunk-
|
|
72
|
-
import "./chunk-
|
|
73
|
-
import "./chunk-4VNS5WPM.js";
|
|
84
|
+
} from "./chunk-6APULWSU.js";
|
|
85
|
+
import "./chunk-KI2EY3WB.js";
|
|
74
86
|
|
|
75
87
|
// src/index.ts
|
|
76
88
|
import { Command as Command28 } from "commander";
|
|
@@ -472,7 +484,7 @@ import chalk6 from "chalk";
|
|
|
472
484
|
import ora from "ora";
|
|
473
485
|
import { spawn } from "child_process";
|
|
474
486
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
475
|
-
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";
|
|
476
488
|
import { dirname as dirname2, join as join8 } from "path";
|
|
477
489
|
import { fileURLToPath } from "url";
|
|
478
490
|
|
|
@@ -998,20 +1010,10 @@ async function resolvePorts(prefs) {
|
|
|
998
1010
|
|
|
999
1011
|
// src/lib/edge-preflight.ts
|
|
1000
1012
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
1001
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync6,
|
|
1013
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1002
1014
|
import { join as join6 } from "path";
|
|
1003
1015
|
import chalk5 from "chalk";
|
|
1004
1016
|
import { isCancel, log, note, select } from "@clack/prompts";
|
|
1005
|
-
function isSafePath(p) {
|
|
1006
|
-
return /^\/[A-Za-z0-9._/-]+$/.test(p);
|
|
1007
|
-
}
|
|
1008
|
-
function readCertFile(p) {
|
|
1009
|
-
try {
|
|
1010
|
-
return readFileSync4(p, "utf8");
|
|
1011
|
-
} catch {
|
|
1012
|
-
return null;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
1017
|
async function planAndApplyHostEdge(opts, overrides = {}) {
|
|
1016
1018
|
const deps = { ...defaultDeps(), ...overrides };
|
|
1017
1019
|
if (deps.platform !== "linux") return { proceed: true };
|
|
@@ -1029,7 +1031,7 @@ async function planAndApplyHostEdge(opts, overrides = {}) {
|
|
|
1029
1031
|
const { sites, warnings } = await deps.importSites(executor, status);
|
|
1030
1032
|
const action2 = await resolveAction(opts.edge, { status, owner, sites, warnings }, deps);
|
|
1031
1033
|
if (action2 === "cancel") return { proceed: false };
|
|
1032
|
-
const certPems = action2 === "migrate" ?
|
|
1034
|
+
const certPems = action2 === "migrate" ? await deps.collectCerts(executor, sites, { status }) : void 0;
|
|
1033
1035
|
await deps.beginEdgeTakeover(
|
|
1034
1036
|
executor,
|
|
1035
1037
|
status,
|
|
@@ -1106,7 +1108,12 @@ async function offerStoppedProxyImport(executor, deps) {
|
|
|
1106
1108
|
if (!await deps.confirmStoppedImport({ proxy, count: sites.length })) {
|
|
1107
1109
|
return { proceed: true };
|
|
1108
1110
|
}
|
|
1109
|
-
return {
|
|
1111
|
+
return {
|
|
1112
|
+
proceed: true,
|
|
1113
|
+
action: "migrate",
|
|
1114
|
+
sites,
|
|
1115
|
+
certPems: await deps.collectCerts(executor, sites, { proxy })
|
|
1116
|
+
};
|
|
1110
1117
|
}
|
|
1111
1118
|
async function completeHostEdge() {
|
|
1112
1119
|
if (process.platform !== "linux") return;
|
|
@@ -1130,17 +1137,57 @@ async function resolveAction(flag, ctx, deps) {
|
|
|
1130
1137
|
importable: ctx.sites.length
|
|
1131
1138
|
});
|
|
1132
1139
|
}
|
|
1133
|
-
function
|
|
1134
|
-
const
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
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}`));
|
|
1142
1160
|
}
|
|
1143
|
-
|
|
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;
|
|
1144
1191
|
}
|
|
1145
1192
|
function defaultDeps() {
|
|
1146
1193
|
return {
|
|
@@ -1170,61 +1217,20 @@ function defaultDeps() {
|
|
|
1170
1217
|
});
|
|
1171
1218
|
return !isCancel(take) && take === "import";
|
|
1172
1219
|
},
|
|
1173
|
-
|
|
1174
|
-
render:
|
|
1175
|
-
|
|
1176
|
-
const lines = sites.map((st) => {
|
|
1177
|
-
const host = (st.serverNames ?? []).join(", ") || "(no server_name)";
|
|
1178
|
-
const dest = st.target.kind === "static" ? `static: ${st.target.root}` : st.target.url;
|
|
1179
|
-
return `${chalk5.bold(host)} \u2192 ${chalk5.dim(dest)}${st.ssl ? chalk5.green(" [TLS]") : ""}`;
|
|
1180
|
-
});
|
|
1181
|
-
note(lines.join("\n"), `Detected ${sites.length} site${sites.length === 1 ? "" : "s"} on ${owner}`);
|
|
1182
|
-
}
|
|
1183
|
-
if (warnings.length > 0) {
|
|
1184
|
-
log.warn(`${warnings.length} config item${warnings.length === 1 ? "" : "s"} won't migrate automatically:`);
|
|
1185
|
-
for (const w of warnings.slice(0, 8)) log.message(chalk5.dim(`\u2022 ${w}`));
|
|
1186
|
-
}
|
|
1187
|
-
},
|
|
1188
|
-
confirm: async ({ owner, known, importable }) => {
|
|
1189
|
-
const choice = await select({
|
|
1190
|
-
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.`,
|
|
1191
|
-
options: [
|
|
1192
|
-
...importable > 0 ? [
|
|
1193
|
-
{
|
|
1194
|
-
value: "migrate",
|
|
1195
|
-
label: `Migrate ${importable} site${importable === 1 ? "" : "s"} & take over`,
|
|
1196
|
-
hint: "import the existing sites into Openship's edge, then take 80/443"
|
|
1197
|
-
}
|
|
1198
|
-
] : [],
|
|
1199
|
-
{
|
|
1200
|
-
value: "takeover",
|
|
1201
|
-
label: "Stop it & take over 80/443",
|
|
1202
|
-
hint: known ? "the existing sites stop being served" : "may interrupt a running service"
|
|
1203
|
-
},
|
|
1204
|
-
{ value: "cancel", label: "Cancel \u2014 leave it running" }
|
|
1205
|
-
],
|
|
1206
|
-
// Default to MIGRATE whenever there are sites we can import: it's the only
|
|
1207
|
-
// option that both gets Openship onto 80/443 and keeps the operator's
|
|
1208
|
-
// existing sites served, so it's the choice they almost always want and
|
|
1209
|
-
// the one that loses nothing on a reflexive Enter.
|
|
1210
|
-
// With nothing importable there's no safe default: a known proxy falls
|
|
1211
|
-
// back to cancel (blind Enter would stop sites that are being served),
|
|
1212
|
-
// and an unidentified port holder to takeover.
|
|
1213
|
-
initialValue: importable > 0 ? "migrate" : known ? "cancel" : "takeover"
|
|
1214
|
-
});
|
|
1215
|
-
return isCancel(choice) ? "cancel" : choice;
|
|
1216
|
-
},
|
|
1220
|
+
collectCerts: collectCertsFromProxy,
|
|
1221
|
+
render: renderEdgeConflict,
|
|
1222
|
+
confirm: confirmEdgeAction,
|
|
1217
1223
|
warn: (message) => console.log(chalk5.yellow(` ${message}`))
|
|
1218
1224
|
};
|
|
1219
1225
|
}
|
|
1220
1226
|
|
|
1221
1227
|
// src/lib/loopback-api.ts
|
|
1222
|
-
import { existsSync as existsSync6, readFileSync as
|
|
1228
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, mkdirSync as mkdirSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
1223
1229
|
import { randomBytes } from "crypto";
|
|
1224
1230
|
import { join as join7 } from "path";
|
|
1225
1231
|
function ensureInternalToken() {
|
|
1226
1232
|
const path2 = join7(OS_DIR, "internal-token");
|
|
1227
|
-
if (existsSync6(path2)) return
|
|
1233
|
+
if (existsSync6(path2)) return readFileSync4(path2, "utf8").trim();
|
|
1228
1234
|
mkdirSync7(OS_DIR, { recursive: true, mode: 448 });
|
|
1229
1235
|
const token = randomBytes(32).toString("hex");
|
|
1230
1236
|
writeFileSync6(path2, token, { mode: 384 });
|
|
@@ -1484,26 +1490,31 @@ async function headlessProvision(opts) {
|
|
|
1484
1490
|
warnings.push(`Custom domain provisioning returned: ${res.data?.error || "failed"}`);
|
|
1485
1491
|
}
|
|
1486
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
|
+
});
|
|
1487
1502
|
let slug = d.slug;
|
|
1488
|
-
let res = await internalPost(
|
|
1489
|
-
port,
|
|
1490
|
-
"/api/system/self-register",
|
|
1491
|
-
{ domainType: "free", slug, publicHost: d.publicHost, dashPort },
|
|
1492
|
-
token
|
|
1493
|
-
);
|
|
1503
|
+
let res = await internalPost(port, "/api/system/self-register", freeBody(slug), token);
|
|
1494
1504
|
for (let attempt = 0; !res.ok && isSlugTaken(res.data) && opts.onSlugTaken && attempt < 5; attempt++) {
|
|
1495
1505
|
const next = await opts.onSlugTaken(slug);
|
|
1496
1506
|
if (!next) break;
|
|
1497
1507
|
slug = next;
|
|
1498
|
-
res = await internalPost(
|
|
1499
|
-
port,
|
|
1500
|
-
"/api/system/self-register",
|
|
1501
|
-
{ domainType: "free", slug, publicHost: d.publicHost, dashPort },
|
|
1502
|
-
token
|
|
1503
|
-
);
|
|
1508
|
+
res = await internalPost(port, "/api/system/self-register", freeBody(slug), token);
|
|
1504
1509
|
}
|
|
1505
1510
|
domainRegistered = res.ok;
|
|
1506
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
|
+
}
|
|
1507
1518
|
if (!res.ok) {
|
|
1508
1519
|
warnings.push(
|
|
1509
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.`
|
|
@@ -1524,6 +1535,12 @@ function normalizeUrl(raw) {
|
|
|
1524
1535
|
return null;
|
|
1525
1536
|
}
|
|
1526
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
|
+
}
|
|
1527
1544
|
function normalizePublicUrl(raw) {
|
|
1528
1545
|
const url = normalizeUrl(raw);
|
|
1529
1546
|
if (!url) {
|
|
@@ -1539,7 +1556,7 @@ var DIST_DIR = dirname2(fileURLToPath(import.meta.url));
|
|
|
1539
1556
|
var SERVER_DIR = join8(DIST_DIR, "server");
|
|
1540
1557
|
function ensureAuthSecret() {
|
|
1541
1558
|
const path2 = join8(OS_DIR, "auth-secret");
|
|
1542
|
-
if (existsSync7(path2)) return
|
|
1559
|
+
if (existsSync7(path2)) return readFileSync5(path2, "utf8").trim();
|
|
1543
1560
|
mkdirSync8(OS_DIR, { recursive: true, mode: 448 });
|
|
1544
1561
|
const secret = randomBytes2(32).toString("hex");
|
|
1545
1562
|
writeFileSync7(path2, secret, { mode: 384 });
|
|
@@ -1681,7 +1698,7 @@ async function runCompose(opts) {
|
|
|
1681
1698
|
);
|
|
1682
1699
|
process.exit(1);
|
|
1683
1700
|
}
|
|
1684
|
-
const publicUrl =
|
|
1701
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1685
1702
|
const fromSource = sourceBuildDir();
|
|
1686
1703
|
const spinner5 = ora(
|
|
1687
1704
|
fromSource ? `Building Openship from ${fromSource} and starting the stack\u2026` : "Starting Openship via Docker Compose\u2026"
|
|
@@ -1691,8 +1708,10 @@ async function runCompose(opts) {
|
|
|
1691
1708
|
dashboardPort: opts.dashboardPort,
|
|
1692
1709
|
publicUrl,
|
|
1693
1710
|
trustProxy: opts.trustProxy,
|
|
1694
|
-
// commander maps `--no-host-control` to hostControl === false.
|
|
1695
|
-
|
|
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
|
|
1696
1715
|
});
|
|
1697
1716
|
if (!res.ok) {
|
|
1698
1717
|
spinner5.fail("docker compose failed to start the stack");
|
|
@@ -1740,7 +1759,7 @@ async function runFromSource(opts) {
|
|
|
1740
1759
|
await runForeground(opts, src);
|
|
1741
1760
|
}
|
|
1742
1761
|
async function startService(opts, runOpts = {}) {
|
|
1743
|
-
const publicUrl =
|
|
1762
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1744
1763
|
if (opts.dryRun) {
|
|
1745
1764
|
const p = preview({
|
|
1746
1765
|
port: opts.port,
|
|
@@ -1839,7 +1858,7 @@ async function runForeground(opts, source) {
|
|
|
1839
1858
|
});
|
|
1840
1859
|
const port = String(resolved.api);
|
|
1841
1860
|
const dashPort = String(resolved.dashboard);
|
|
1842
|
-
const publicUrl =
|
|
1861
|
+
const publicUrl = effectivePublicUrl(opts.publicUrl);
|
|
1843
1862
|
const managedEdge = Boolean(opts.managedEdge && publicUrl);
|
|
1844
1863
|
const dataDir = opts.dataDir || join8(OS_DIR, "data");
|
|
1845
1864
|
mkdirSync8(dataDir, { recursive: true });
|
|
@@ -1861,9 +1880,12 @@ async function runForeground(opts, source) {
|
|
|
1861
1880
|
if (!source) {
|
|
1862
1881
|
env.OPENSHIP_MIGRATIONS_DIR = join8(SERVER_DIR, "migrations");
|
|
1863
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;
|
|
1864
1885
|
}
|
|
1865
1886
|
env.OPENSHIP_REQUIRE_AUTH = "true";
|
|
1866
1887
|
env.INTERNAL_TOKEN = ensureInternalToken();
|
|
1888
|
+
if (!env.OPENSHIP_AUTH_MODE) env.OPENSHIP_AUTH_MODE = "local";
|
|
1867
1889
|
env.OPENSHIP_API_HOST = "127.0.0.1";
|
|
1868
1890
|
env.OPENSHIP_DASHBOARD_PORT = dashPort;
|
|
1869
1891
|
env.OPENSHIP_INSTANCE_LOG = instanceLogPath;
|
|
@@ -1951,7 +1973,7 @@ async function runForeground(opts, source) {
|
|
|
1951
1973
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1952
1974
|
try {
|
|
1953
1975
|
const bundle = await ensureDashboard({
|
|
1954
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.4.
|
|
1976
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.4.6"}`,
|
|
1955
1977
|
onProgress: (received, total) => {
|
|
1956
1978
|
if (total) {
|
|
1957
1979
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -2220,7 +2242,7 @@ var initCommand = new Command7("init").description("Link the current directory t
|
|
|
2220
2242
|
|
|
2221
2243
|
// src/commands/config.ts
|
|
2222
2244
|
import { Command as Command8 } from "commander";
|
|
2223
|
-
import { existsSync as existsSync10, readFileSync as
|
|
2245
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6, writeFileSync as writeFileSync9 } from "fs";
|
|
2224
2246
|
import { join as join10 } from "path";
|
|
2225
2247
|
var SCHEMA_URL = "https://openship.io/openship.schema.json";
|
|
2226
2248
|
var CONFIG_FILE = "openship.json";
|
|
@@ -2241,7 +2263,7 @@ function detectHints(dir) {
|
|
|
2241
2263
|
const pkgPath = join10(dir, "package.json");
|
|
2242
2264
|
if (existsSync10(pkgPath)) {
|
|
2243
2265
|
try {
|
|
2244
|
-
const pkg = JSON.parse(
|
|
2266
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
2245
2267
|
const runner = hints.packageManager ?? "npm";
|
|
2246
2268
|
const exec = runner === "npm" ? "npm run" : runner;
|
|
2247
2269
|
if (pkg.scripts?.build) hints.buildCommand = `${exec} build`;
|
|
@@ -2277,7 +2299,7 @@ var validateCmd = new Command8("validate").description("Validate an openship.jso
|
|
|
2277
2299
|
else err(`Not found: ${path2}`);
|
|
2278
2300
|
process.exit(1);
|
|
2279
2301
|
}
|
|
2280
|
-
const { config, errors, warnings } = parseOpenshipConfigJson(
|
|
2302
|
+
const { config, errors, warnings } = parseOpenshipConfigJson(readFileSync6(path2, "utf8"));
|
|
2281
2303
|
const valid = errors.length === 0 && config !== null;
|
|
2282
2304
|
if (isJsonMode()) {
|
|
2283
2305
|
printJson({ valid, errors, warnings });
|
|
@@ -2350,11 +2372,11 @@ var contextCommand = new Command9("context").alias("ctx").description("Manage co
|
|
|
2350
2372
|
// src/commands/status.ts
|
|
2351
2373
|
import { Command as Command10 } from "commander";
|
|
2352
2374
|
import chalk9 from "chalk";
|
|
2353
|
-
import { readFileSync as
|
|
2375
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
2354
2376
|
import { join as join11 } from "path";
|
|
2355
2377
|
function readPorts() {
|
|
2356
2378
|
try {
|
|
2357
|
-
return JSON.parse(
|
|
2379
|
+
return JSON.parse(readFileSync7(join11(OS_DIR, "ports.json"), "utf8"));
|
|
2358
2380
|
} catch {
|
|
2359
2381
|
return {};
|
|
2360
2382
|
}
|
|
@@ -2418,7 +2440,7 @@ import { intro, outro, note as note2, select as select3, log as log3, spinner as
|
|
|
2418
2440
|
|
|
2419
2441
|
// src/lib/repair.ts
|
|
2420
2442
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
2421
|
-
import { existsSync as existsSync12, readFileSync as
|
|
2443
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
|
|
2422
2444
|
import { join as join13 } from "path";
|
|
2423
2445
|
import chalk10 from "chalk";
|
|
2424
2446
|
import { spinner, log as log2, select as select2, isCancel as isCancel3, cancel } from "@clack/prompts";
|
|
@@ -2532,7 +2554,7 @@ function ensure(value) {
|
|
|
2532
2554
|
function storedPorts() {
|
|
2533
2555
|
try {
|
|
2534
2556
|
const p = join13(OS_DIR, "ports.json");
|
|
2535
|
-
return existsSync12(p) ? JSON.parse(
|
|
2557
|
+
return existsSync12(p) ? JSON.parse(readFileSync8(p, "utf8")) : {};
|
|
2536
2558
|
} catch {
|
|
2537
2559
|
return {};
|
|
2538
2560
|
}
|
|
@@ -2584,7 +2606,7 @@ function lastServiceError() {
|
|
|
2584
2606
|
const p = join13(LOG_DIR2, name);
|
|
2585
2607
|
if (!existsSync12(p)) continue;
|
|
2586
2608
|
try {
|
|
2587
|
-
const lines =
|
|
2609
|
+
const lines = readFileSync8(p, "utf8").trim().split("\n");
|
|
2588
2610
|
const hit = [...lines].reverse().find((l) => /error|locked|aborted|malformed|corrupt|throw|cannot|EADDRINUSE/i.test(l));
|
|
2589
2611
|
if (hit) return hit.trim().slice(0, 240);
|
|
2590
2612
|
} catch {
|
|
@@ -3011,7 +3033,7 @@ import { execFileSync as execFileSync4 } from "child_process";
|
|
|
3011
3033
|
import ora2 from "ora";
|
|
3012
3034
|
|
|
3013
3035
|
// src/lib/project-link.ts
|
|
3014
|
-
import { readFileSync as
|
|
3036
|
+
import { readFileSync as readFileSync9, existsSync as existsSync14 } from "fs";
|
|
3015
3037
|
import { join as join14, dirname as dirname3, parse } from "path";
|
|
3016
3038
|
var LINK_REL = join14(".openship", "project.json");
|
|
3017
3039
|
function findProjectLinkPath(from = process.cwd()) {
|
|
@@ -3028,7 +3050,7 @@ function readProjectLink(from) {
|
|
|
3028
3050
|
const path2 = findProjectLinkPath(from);
|
|
3029
3051
|
if (!path2) return null;
|
|
3030
3052
|
try {
|
|
3031
|
-
return JSON.parse(
|
|
3053
|
+
return JSON.parse(readFileSync9(path2, "utf8"));
|
|
3032
3054
|
} catch {
|
|
3033
3055
|
return null;
|
|
3034
3056
|
}
|
|
@@ -3036,7 +3058,7 @@ function readProjectLink(from) {
|
|
|
3036
3058
|
|
|
3037
3059
|
// src/lib/folder-deploy.ts
|
|
3038
3060
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
3039
|
-
import { readFileSync as
|
|
3061
|
+
import { readFileSync as readFileSync10, existsSync as existsSync15, rmSync as rmSync4 } from "fs";
|
|
3040
3062
|
import { tmpdir } from "os";
|
|
3041
3063
|
import { join as join15, basename } from "path";
|
|
3042
3064
|
function detectPackageManager(dir) {
|
|
@@ -3086,7 +3108,7 @@ async function deployFolder(opts) {
|
|
|
3086
3108
|
);
|
|
3087
3109
|
step("Uploading source");
|
|
3088
3110
|
try {
|
|
3089
|
-
const body =
|
|
3111
|
+
const body = readFileSync10(tarball);
|
|
3090
3112
|
const up = session.upload;
|
|
3091
3113
|
const method = up.method || "POST";
|
|
3092
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 });
|
|
@@ -4798,7 +4820,7 @@ var domainCommand = new Command17("domain").description("Manage custom domains,
|
|
|
4798
4820
|
import { Command as Command18 } from "commander";
|
|
4799
4821
|
import chalk15 from "chalk";
|
|
4800
4822
|
import ora4 from "ora";
|
|
4801
|
-
var INSTALLABLE = ["docker", "git", "
|
|
4823
|
+
var INSTALLABLE = ["docker", "git", "edge", "rsync"];
|
|
4802
4824
|
function guard(fn) {
|
|
4803
4825
|
return async (...args) => {
|
|
4804
4826
|
if (!getToken()) {
|
|
@@ -5092,7 +5114,7 @@ var serverCommand = server;
|
|
|
5092
5114
|
// src/commands/system.ts
|
|
5093
5115
|
import { Command as Command19 } from "commander";
|
|
5094
5116
|
import ora5 from "ora";
|
|
5095
|
-
import { readFileSync as
|
|
5117
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
5096
5118
|
import { createInterface as createInterface6 } from "readline/promises";
|
|
5097
5119
|
import { stdin as input5, stdout as output5 } from "process";
|
|
5098
5120
|
async function guarded(fn) {
|
|
@@ -5418,7 +5440,7 @@ dataTransferCommand.command("import").description("Import an instance export fil
|
|
|
5418
5440
|
}
|
|
5419
5441
|
let file;
|
|
5420
5442
|
try {
|
|
5421
|
-
file = JSON.parse(
|
|
5443
|
+
file = JSON.parse(readFileSync11(opts.file, "utf8"));
|
|
5422
5444
|
} catch {
|
|
5423
5445
|
err(`
|
|
5424
5446
|
Could not read or parse ${opts.file}.
|
|
@@ -5769,7 +5791,7 @@ var mailCommand = new Command20("mail").description("Self-hosted mail server (iR
|
|
|
5769
5791
|
// src/commands/backup.ts
|
|
5770
5792
|
import { Command as Command21 } from "commander";
|
|
5771
5793
|
import ora7 from "ora";
|
|
5772
|
-
import { readFileSync as
|
|
5794
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
5773
5795
|
async function guard3(fn) {
|
|
5774
5796
|
try {
|
|
5775
5797
|
await fn();
|
|
@@ -6062,7 +6084,7 @@ destinationCmd.command("create").description("Create a backup destination").requ
|
|
|
6062
6084
|
let sftpPrivateKey = opts.sftpPrivateKey;
|
|
6063
6085
|
if (opts.sftpPrivateKeyFile) {
|
|
6064
6086
|
try {
|
|
6065
|
-
sftpPrivateKey =
|
|
6087
|
+
sftpPrivateKey = readFileSync12(opts.sftpPrivateKeyFile, "utf8");
|
|
6066
6088
|
} catch {
|
|
6067
6089
|
throw new Error(`Cannot read key file: ${opts.sftpPrivateKeyFile}`);
|
|
6068
6090
|
}
|
|
@@ -6254,11 +6276,11 @@ var apiCommand = new Command23("api").description("Make an authenticated request
|
|
|
6254
6276
|
import { Command as Command24 } from "commander";
|
|
6255
6277
|
import chalk19 from "chalk";
|
|
6256
6278
|
import { intro as intro2, outro as outro2, password as passwordPrompt, isCancel as isCancel4, cancel as cancel3, log as log4 } from "@clack/prompts";
|
|
6257
|
-
import { readFileSync as
|
|
6279
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
6258
6280
|
import { join as join16 } from "path";
|
|
6259
6281
|
function resolvedApiPort() {
|
|
6260
6282
|
try {
|
|
6261
|
-
return JSON.parse(
|
|
6283
|
+
return JSON.parse(readFileSync13(join16(OS_DIR, "ports.json"), "utf8")).api;
|
|
6262
6284
|
} catch {
|
|
6263
6285
|
return void 0;
|
|
6264
6286
|
}
|
|
@@ -6312,7 +6334,7 @@ var resetAdminCommand = new Command24("reset-admin-password").description("Reset
|
|
|
6312
6334
|
|
|
6313
6335
|
// src/commands/install.ts
|
|
6314
6336
|
import { Command as Command25 } from "commander";
|
|
6315
|
-
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";
|
|
6316
6338
|
import { spawn as spawn2, spawnSync as spawnSync6 } from "child_process";
|
|
6317
6339
|
import { homedir as homedir3 } from "os";
|
|
6318
6340
|
import { join as join17 } from "path";
|
|
@@ -6449,7 +6471,7 @@ var installCommand = new Command25("install").description("Download and install
|
|
|
6449
6471
|
try {
|
|
6450
6472
|
let sidecarBody;
|
|
6451
6473
|
if (existsSync16(sidecarPath) && !downloaded) {
|
|
6452
|
-
sidecarBody =
|
|
6474
|
+
sidecarBody = readFileSync14(sidecarPath, "utf8");
|
|
6453
6475
|
} else {
|
|
6454
6476
|
sidecarBody = await fetchSidecar(sidecarUrl);
|
|
6455
6477
|
}
|
|
@@ -6560,7 +6582,7 @@ function detectPackageManager2(override) {
|
|
|
6560
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) => {
|
|
6561
6583
|
const source = readSourceInstall();
|
|
6562
6584
|
if (source) return runSourceUpdate(source, opts);
|
|
6563
|
-
const current = "0.4.
|
|
6585
|
+
const current = "0.4.6";
|
|
6564
6586
|
let latest;
|
|
6565
6587
|
try {
|
|
6566
6588
|
latest = (await resolveLatestTag()).replace(/^v/, "");
|
|
@@ -6595,13 +6617,13 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
|
|
|
6595
6617
|
return;
|
|
6596
6618
|
}
|
|
6597
6619
|
if (readInstallMethod() === "compose") {
|
|
6598
|
-
const
|
|
6620
|
+
const applied = composeUpdate(latest);
|
|
6599
6621
|
if (isJsonMode()) {
|
|
6600
|
-
printJson({ updated: true, from: current, to: latest, via: pm, method: "compose",
|
|
6601
|
-
} else if (
|
|
6602
|
-
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.`);
|
|
6603
6625
|
} else {
|
|
6604
|
-
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.`);
|
|
6605
6627
|
process.exitCode = 1;
|
|
6606
6628
|
}
|
|
6607
6629
|
return;
|
|
@@ -6618,7 +6640,7 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
|
|
|
6618
6640
|
|
|
6619
6641
|
// src/commands/cache.ts
|
|
6620
6642
|
import { Command as Command27 } from "commander";
|
|
6621
|
-
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";
|
|
6622
6644
|
import { join as join18 } from "path";
|
|
6623
6645
|
function listAssets() {
|
|
6624
6646
|
if (!existsSync17(RELEASES_DIR)) return [];
|
|
@@ -6667,7 +6689,7 @@ var verifyCmd2 = new Command27("verify").description("Re-hash cached assets and
|
|
|
6667
6689
|
results.push({ tag: a.tag, asset: a.name, result: "no-sidecar" });
|
|
6668
6690
|
continue;
|
|
6669
6691
|
}
|
|
6670
|
-
const expected = parseSha256(
|
|
6692
|
+
const expected = parseSha256(readFileSync15(`${a.path}.sha256`, "utf8"));
|
|
6671
6693
|
const actual = await hashFile(a.path);
|
|
6672
6694
|
const okMatch = expected !== null && expected === actual;
|
|
6673
6695
|
if (!okMatch) bad += 1;
|
|
@@ -6703,7 +6725,7 @@ var cacheCommand = new Command27("cache").description("Manage the local download
|
|
|
6703
6725
|
import chalk20 from "chalk";
|
|
6704
6726
|
import open2 from "open";
|
|
6705
6727
|
import { createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
|
|
6706
|
-
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";
|
|
6707
6729
|
import { join as join19 } from "path";
|
|
6708
6730
|
import {
|
|
6709
6731
|
intro as intro3,
|
|
@@ -6891,6 +6913,21 @@ ${pad("Login")}${opts.adminEmail} ${chalk20.dim("(email + password you set)")}
|
|
|
6891
6913
|
);
|
|
6892
6914
|
outro3(opts.byo ? chalk20.dim("Point your reverse proxy at the dashboard port above.") : chalk20.green("Happy shipping."));
|
|
6893
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
|
+
}
|
|
6894
6931
|
async function runWizard() {
|
|
6895
6932
|
const resuming = isSetupInProgress();
|
|
6896
6933
|
intro3(`${chalk20.bgCyan(chalk20.black(" Openship "))}${chalk20.dim(" setup")}`);
|
|
@@ -7112,7 +7149,7 @@ async function runWizard() {
|
|
|
7112
7149
|
}
|
|
7113
7150
|
}
|
|
7114
7151
|
}
|
|
7115
|
-
const uiTag = `v${"0.4.
|
|
7152
|
+
const uiTag = `v${"0.4.6"}`;
|
|
7116
7153
|
if (method === "bare") {
|
|
7117
7154
|
const dl = spinner4();
|
|
7118
7155
|
dl.start("Pulling the Openship dist from GitHub");
|
|
@@ -7180,7 +7217,7 @@ async function runWizard() {
|
|
|
7180
7217
|
const up = composeUp({
|
|
7181
7218
|
publicUrl,
|
|
7182
7219
|
trustProxy: behindProxy,
|
|
7183
|
-
version: "0.4.
|
|
7220
|
+
version: "0.4.6",
|
|
7184
7221
|
noHostControl: !allowHostControl
|
|
7185
7222
|
});
|
|
7186
7223
|
if (!up.ok) {
|
|
@@ -7317,93 +7354,49 @@ async function runWizard() {
|
|
|
7317
7354
|
await internalPost(port, "/api/system/self-register", { domainType: "byo" });
|
|
7318
7355
|
} else {
|
|
7319
7356
|
cloudEmail = cloud.email;
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
const res = await internalPost(port, "/api/system/self-register", {
|
|
7325
|
-
domainType: "free",
|
|
7326
|
-
slug: regSlug,
|
|
7327
|
-
publicHost: domainPlan.publicHost,
|
|
7328
|
-
dashPort: Number(started.dashPort)
|
|
7329
|
-
});
|
|
7330
|
-
if (res.ok && res.data?.url) {
|
|
7331
|
-
liveUrl = res.data.url;
|
|
7332
|
-
s2.stop(`Free domain live: ${res.data.url}`);
|
|
7333
|
-
break;
|
|
7334
|
-
}
|
|
7335
|
-
s2.stop(`Couldn't register ${regSlug}.opsh.io: ${res.data?.error || "failed"}`, 1);
|
|
7336
|
-
const next = ensure2(
|
|
7337
|
-
await select4({
|
|
7338
|
-
message: "Try a different subdomain?",
|
|
7339
|
-
options: [
|
|
7340
|
-
{ value: "retry", label: "Pick another subdomain" },
|
|
7341
|
-
{ value: "skip", label: "Skip for now", hint: "log in on this server; add a domain later in Settings \u2192 Cloud" }
|
|
7342
|
-
]
|
|
7343
|
-
})
|
|
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."
|
|
7344
7361
|
);
|
|
7345
|
-
if (next === "skip") break;
|
|
7346
|
-
regSlug = ensure2(
|
|
7347
|
-
await text({
|
|
7348
|
-
message: "Choose your subdomain",
|
|
7349
|
-
placeholder: "my-openship",
|
|
7350
|
-
initialValue: regSlug,
|
|
7351
|
-
validate: (v) => v && SLUG_RE2.test(v.trim().toLowerCase()) ? void 0 : "Lowercase letters, digits, hyphens"
|
|
7352
|
-
})
|
|
7353
|
-
).trim().toLowerCase();
|
|
7354
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);
|
|
7355
7394
|
}
|
|
7356
7395
|
} else if (domainPlan.type === "custom") {
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
const
|
|
7361
|
-
const status = pf.ok ? pf.data?.status : void 0;
|
|
7362
|
-
const importable = pf.ok && Array.isArray(pf.data?.sites) ? pf.data.sites.length : 0;
|
|
7363
|
-
if (status && !status.canProceedClean && status.occupants?.length) {
|
|
7364
|
-
const owner = status.occupants.map((o) => o.command ?? `port ${o.port}`).join(", ");
|
|
7365
|
-
const known = status.classification === "known";
|
|
7366
|
-
const sites = pf.ok && Array.isArray(pf.data?.sites) ? pf.data.sites : [];
|
|
7367
|
-
if (sites.length > 0) {
|
|
7368
|
-
const lines = sites.map((st) => {
|
|
7369
|
-
const host = (st.serverNames ?? []).join(", ") || "(no server_name)";
|
|
7370
|
-
const dest = st.target?.kind === "static" ? `static: ${st.target?.root ?? ""}` : st.target?.url ?? "";
|
|
7371
|
-
return `${chalk20.bold(host)} \u2192 ${chalk20.dim(dest)}${st.ssl ? chalk20.green(" [TLS]") : ""}`;
|
|
7372
|
-
});
|
|
7373
|
-
note3(lines.join("\n"), `Detected ${sites.length} site${sites.length === 1 ? "" : "s"} on ${owner}`);
|
|
7374
|
-
}
|
|
7375
|
-
const warns = pf.ok && Array.isArray(pf.data?.warnings) ? pf.data.warnings : [];
|
|
7376
|
-
if (warns.length > 0) {
|
|
7377
|
-
log5.warn(`${warns.length} config item${warns.length === 1 ? "" : "s"} won't migrate automatically:`);
|
|
7378
|
-
for (const w of warns.slice(0, 8)) log5.message(chalk20.dim(`\u2022 ${w}`));
|
|
7379
|
-
}
|
|
7380
|
-
const choice = ensure2(
|
|
7381
|
-
await select4({
|
|
7382
|
-
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.`,
|
|
7383
|
-
options: [
|
|
7384
|
-
...importable > 0 ? [{
|
|
7385
|
-
value: "migrate",
|
|
7386
|
-
label: `Migrate ${importable} site${importable === 1 ? "" : "s"} & take over`,
|
|
7387
|
-
hint: "import the existing sites into Openship, then take 80/443"
|
|
7388
|
-
}] : [],
|
|
7389
|
-
{
|
|
7390
|
-
value: "override",
|
|
7391
|
-
label: "Stop it & take over 80/443",
|
|
7392
|
-
hint: known ? "the existing sites stop being served" : "may interrupt a running service"
|
|
7393
|
-
},
|
|
7394
|
-
{ value: "cancel", label: "Cancel \u2014 leave it running" }
|
|
7395
|
-
],
|
|
7396
|
-
// Same default as the `up` preflight (edge-preflight.ts): migrate when
|
|
7397
|
-
// there are importable sites — it takes 80/443 without dropping any of
|
|
7398
|
-
// them. Otherwise a known proxy defaults to cancel (Enter must not stop
|
|
7399
|
-
// sites that are being served) and an unidentified holder to takeover.
|
|
7400
|
-
initialValue: importable > 0 ? "migrate" : known ? "cancel" : "override"
|
|
7401
|
-
})
|
|
7402
|
-
);
|
|
7403
|
-
if (choice === "cancel") proceedCustom = false;
|
|
7404
|
-
else if (choice === "migrate") edgeMigrate = true;
|
|
7405
|
-
else edgeTakeover = true;
|
|
7406
|
-
}
|
|
7396
|
+
const edge = await promptLocalEdgeTakeover(port);
|
|
7397
|
+
const proceedCustom = edge.proceed;
|
|
7398
|
+
const edgeTakeover = edge.edgeTakeover;
|
|
7399
|
+
const edgeMigrate = edge.edgeMigrate;
|
|
7407
7400
|
if (!proceedCustom) {
|
|
7408
7401
|
log5.warn(
|
|
7409
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."
|
|
@@ -7458,13 +7451,16 @@ async function runWizard() {
|
|
|
7458
7451
|
function storedPorts2() {
|
|
7459
7452
|
const p = join19(OS_DIR, "ports.json");
|
|
7460
7453
|
try {
|
|
7461
|
-
return existsSync18(p) ? JSON.parse(
|
|
7454
|
+
return existsSync18(p) ? JSON.parse(readFileSync16(p, "utf8")) : {};
|
|
7462
7455
|
} catch {
|
|
7463
7456
|
return {};
|
|
7464
7457
|
}
|
|
7465
7458
|
}
|
|
7466
7459
|
async function runControl() {
|
|
7467
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;
|
|
7468
7464
|
const ports = storedPorts2();
|
|
7469
7465
|
const apiPort2 = String(ports.api ?? 4e3);
|
|
7470
7466
|
const dashUrl = `http://localhost:${ports.dashboard ?? 3001}`;
|
|
@@ -7473,10 +7469,10 @@ async function runControl() {
|
|
|
7473
7469
|
intro3(`${chalk20.bgCyan(chalk20.black(" Openship "))}${chalk20.dim(" control")}`);
|
|
7474
7470
|
note3(
|
|
7475
7471
|
`${chalk20.dim("URL".padEnd(11))}${chalk20.bold(primaryUrl)}
|
|
7476
|
-
${chalk20.dim("Service".padEnd(11))}${
|
|
7472
|
+
${chalk20.dim("Service".padEnd(11))}${running ? chalk20.green("running") : chalk20.yellow("stopped")}
|
|
7477
7473
|
${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
7478
7474
|
` + (ports.api ? `${chalk20.dim("API".padEnd(11))}http://localhost:${ports.api}
|
|
7479
|
-
` : "") + `${chalk20.dim("Manager".padEnd(11))}${
|
|
7475
|
+
` : "") + `${chalk20.dim("Manager".padEnd(11))}${managerLabel}`,
|
|
7480
7476
|
"Openship is already set up"
|
|
7481
7477
|
);
|
|
7482
7478
|
const corrupted = looksCorrupted();
|
|
@@ -7489,7 +7485,7 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7489
7485
|
options: [
|
|
7490
7486
|
...corrupted ? [{ value: "repair", label: "Repair database", hint: "backup \u2192 heal \u2192 verify" }] : [],
|
|
7491
7487
|
{ value: "open", label: "Open the dashboard" },
|
|
7492
|
-
|
|
7488
|
+
running ? { value: "restart", label: "Restart the service" } : { value: "start", label: "Start the service" },
|
|
7493
7489
|
{ value: "stop", label: "Stop the service", hint: "won't restart on boot" },
|
|
7494
7490
|
...corrupted ? [] : [{ value: "repair", label: "Repair database", hint: "backup \u2192 heal a corrupt DB" }],
|
|
7495
7491
|
{ value: "reset", label: "Reset admin password", hint: "sets a local email + password login" },
|
|
@@ -7509,15 +7505,31 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7509
7505
|
});
|
|
7510
7506
|
outro3(chalk20.dim(`Opening ${primaryUrl}`));
|
|
7511
7507
|
return;
|
|
7512
|
-
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
|
+
}
|
|
7513
7514
|
await startService({});
|
|
7514
7515
|
return;
|
|
7516
|
+
}
|
|
7515
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
|
+
}
|
|
7516
7523
|
const r = restart();
|
|
7517
7524
|
outro3(r.restarted ? chalk20.green("Restarted.") : chalk20.yellow(r.detail));
|
|
7518
7525
|
return;
|
|
7519
7526
|
}
|
|
7520
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
|
+
}
|
|
7521
7533
|
const r = stop();
|
|
7522
7534
|
outro3(chalk20.green(`Stopped. ${chalk20.dim(r.detail)}`));
|
|
7523
7535
|
return;
|
|
@@ -7542,10 +7554,11 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7542
7554
|
|
|
7543
7555
|
// src/index.ts
|
|
7544
7556
|
var program = new Command28();
|
|
7545
|
-
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) => {
|
|
7546
7558
|
if (thisCommand.opts().json) setJsonMode(true);
|
|
7547
7559
|
}).action(async () => {
|
|
7548
|
-
|
|
7560
|
+
const installed = serviceStatus().installed || readInstallMethod() === "compose";
|
|
7561
|
+
if (installed && !isSetupInProgress()) await runControl();
|
|
7549
7562
|
else await runWizard();
|
|
7550
7563
|
});
|
|
7551
7564
|
program.addCommand(upCommand);
|