@rakay-technology/kraft 0.7.4
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 +263 -0
- package/dist/bare-HL2GUYE2.js +27 -0
- package/dist/bowser-HNOTPGJO.js +2825 -0
- package/dist/chunk-3CJLKL6E.js +124 -0
- package/dist/chunk-3NQQXMDR.js +2098 -0
- package/dist/chunk-42WQABXM.js +439 -0
- package/dist/chunk-5GPXMTE4.js +25 -0
- package/dist/chunk-AJ4QZLZ2.js +1069 -0
- package/dist/chunk-AO252K7Z.js +137 -0
- package/dist/chunk-BQMFIXHI.js +975 -0
- package/dist/chunk-DM3PKWDC.js +2453 -0
- package/dist/chunk-DOD2BXHQ.js +1364 -0
- package/dist/chunk-DRK3MEDS.js +2870 -0
- package/dist/chunk-EW4PHKB2.js +13914 -0
- package/dist/chunk-HMJUFZK7.js +340 -0
- package/dist/chunk-I2TOOF2A.js +517 -0
- package/dist/chunk-I3DPMTSF.js +29 -0
- package/dist/chunk-JSCZT76F.js +2588 -0
- package/dist/chunk-MNV2QFHW.js +138 -0
- package/dist/chunk-MOLPYPVH.js +2529 -0
- package/dist/chunk-N4OALTFK.js +295 -0
- package/dist/chunk-OFXBNFNL.js +458 -0
- package/dist/chunk-ONKEYSMY.js +1388 -0
- package/dist/chunk-PDW4L3NV.js +17 -0
- package/dist/chunk-PNNXWA2A.js +1947 -0
- package/dist/chunk-PNRPKRJU.js +11105 -0
- package/dist/chunk-PVOWHIND.js +26781 -0
- package/dist/chunk-PXKCZB2I.js +46 -0
- package/dist/chunk-PZVKPCKE.js +475 -0
- package/dist/chunk-QWHBRY2K.js +4945 -0
- package/dist/chunk-RFOBMHQ7.js +338 -0
- package/dist/chunk-RHLNVZMS.js +28 -0
- package/dist/chunk-RVER2EOO.js +577 -0
- package/dist/chunk-S3QBGGVP.js +81 -0
- package/dist/chunk-TAML5WMA.js +198 -0
- package/dist/chunk-THTEUDBC.js +3188 -0
- package/dist/chunk-WYNM7L22.js +329 -0
- package/dist/chunk-XGCG4MD5.js +102 -0
- package/dist/chunk-XVKUFMIB.js +148 -0
- package/dist/chunk-XZYFZ6A5.js +50 -0
- package/dist/chunk-Y7PVJUXJ.js +2275 -0
- package/dist/chunk-YRSZPVMB.js +306 -0
- package/dist/chunk-YZUKHG3S.js +362 -0
- package/dist/chunk-ZVFS4LUA.js +116 -0
- package/dist/chunk-ZWLDLTJP.js +1417 -0
- package/dist/detect-676SNZK4.js +48 -0
- package/dist/dist-es-2YRDXMUU.js +73 -0
- package/dist/dist-es-CCVZEFRZ.js +91 -0
- package/dist/dist-es-EDUSMF6Q.js +488 -0
- package/dist/dist-es-IOH6G4GM.js +380 -0
- package/dist/dist-es-KWSMDPIP.js +26 -0
- package/dist/dist-es-UYDDOVZ3.js +173 -0
- package/dist/dist-es-XUOR4NQN.js +321 -0
- package/dist/docker-GOT3Q7DJ.js +41 -0
- package/dist/docker-edge-executor-VO6JHHW2.js +19 -0
- package/dist/edge-import-NFCHIW7G.js +50 -0
- package/dist/edge-preflight-QUJ757C6.js +45 -0
- package/dist/ensure-container-edge-Q7IZXHGM.js +38 -0
- package/dist/event-streams-TR4GAC53.js +46 -0
- package/dist/executor-GKXKN52K.js +42 -0
- package/dist/host-channel-preflight-Z6HYSPKO.js +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9469 -0
- package/dist/loadSso-UGF4JMRK.js +581 -0
- package/dist/local-executor-OMMDKXCM.js +13 -0
- package/dist/nginx-VITTWZZU.js +42 -0
- package/dist/node-bootstrap.js +277 -0
- package/dist/node-entry.js +55 -0
- package/dist/noop-CLLJHCPL.js +11 -0
- package/dist/openresty-lua-6I3Z6PEQ.js +90 -0
- package/dist/privilege-UQAI2HV4.js +20 -0
- 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 +702 -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 +11 -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 +101 -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 +39 -0
- package/dist/server/engine/update/ldap/update-ldap-dovecot-2.3.py +69 -0
- package/dist/server/index.js +349016 -0
- package/dist/server/lua/geo_country.lua +127 -0
- package/dist/server/lua/maxminddb.lua +403 -0
- package/dist/server/lua/mgmt_api.lua +654 -0
- package/dist/server/lua/pipe_stream.lua +103 -0
- package/dist/server/lua/rules_guard.lua +132 -0
- package/dist/server/lua/rules_lib.lua +176 -0
- package/dist/server/lua/site_logger.lua +405 -0
- package/dist/server/lua/webhook_handler.lua +126 -0
- package/dist/server/migrations/0000_init.sql +666 -0
- package/dist/server/migrations/0001_brief_tomorrow_man.sql +47 -0
- package/dist/server/migrations/0002_funny_dazzler.sql +2 -0
- package/dist/server/migrations/0003_third_killer_shrike.sql +1 -0
- package/dist/server/migrations/0004_session_active_org_not_null.sql +10 -0
- package/dist/server/migrations/0005_warm_amazoness.sql +3 -0
- package/dist/server/migrations/0006_lumpy_joystick.sql +1 -0
- package/dist/server/migrations/0007_outgoing_maginty.sql +2 -0
- package/dist/server/migrations/0008_frozen_cutover.sql +3 -0
- package/dist/server/migrations/0009_credits_billing.sql +142 -0
- package/dist/server/migrations/0010_credit_grant_dedupe.sql +14 -0
- package/dist/server/migrations/0011_remove_credit_ledger.sql +23 -0
- package/dist/server/migrations/0012_smart_deploys_and_git_rollback.sql +81 -0
- package/dist/server/migrations/0013_fix_check_run_rollup_unique.sql +38 -0
- package/dist/server/migrations/0014_default_rollback_git.sql +9 -0
- package/dist/server/migrations/0015_billing_idempotency_grants.sql +41 -0
- package/dist/server/migrations/0016_github_auth_high_findings.sql +30 -0
- package/dist/server/migrations/0017_spooky_rumiko_fujikawa.sql +6 -0
- package/dist/server/migrations/0018_calm_shatterstar.sql +1 -0
- package/dist/server/migrations/0019_rename_workspace_install_to_prepare.sql +1 -0
- package/dist/server/migrations/0020_uneven_the_renegades.sql +13 -0
- package/dist/server/migrations/0021_shiny_firestar.sql +2 -0
- package/dist/server/migrations/0022_version_on_success_backfill.sql +6 -0
- package/dist/server/migrations/0023_productive_gorilla_man.sql +17 -0
- package/dist/server/migrations/0024_sleepy_peter_quill.sql +2 -0
- package/dist/server/migrations/0025_smooth_blue_shield.sql +1 -0
- package/dist/server/migrations/0026_mail_backup_source.sql +11 -0
- package/dist/server/migrations/0027_opposite_anthem.sql +6 -0
- package/dist/server/migrations/0028_stale_rogue.sql +18 -0
- package/dist/server/migrations/0029_bouncy_loners.sql +16 -0
- package/dist/server/migrations/0030_bright_darkstar.sql +6 -0
- package/dist/server/migrations/0031_conscious_catseye.sql +13 -0
- package/dist/server/migrations/0032_wet_mimic.sql +51 -0
- package/dist/server/migrations/0033_eminent_molly_hayes.sql +2 -0
- package/dist/server/migrations/0034_nervous_surge.sql +1 -0
- package/dist/server/migrations/0035_thankful_morgan_stark.sql +1 -0
- package/dist/server/migrations/0036_gorgeous_scalphunter.sql +17 -0
- package/dist/server/migrations/0037_clever_makkari.sql +28 -0
- package/dist/server/migrations/0038_young_magneto.sql +1 -0
- package/dist/server/migrations/0039_secret_lady_ursula.sql +15 -0
- package/dist/server/migrations/0040_sharp_red_wolf.sql +16 -0
- package/dist/server/migrations/0041_round_spyke.sql +4 -0
- package/dist/server/migrations/0042_dapper_havok.sql +1 -0
- package/dist/server/migrations/0043_fast_sharon_ventura.sql +15 -0
- package/dist/server/migrations/0044_amused_shape.sql +8 -0
- package/dist/server/migrations/0045_amusing_korath.sql +1 -0
- package/dist/server/migrations/0046_white_harrier.sql +35 -0
- package/dist/server/migrations/0047_sloppy_strong_guy.sql +2 -0
- package/dist/server/migrations/0048_funny_emma_frost.sql +2 -0
- package/dist/server/migrations/0049_nappy_piledriver.sql +3 -0
- package/dist/server/migrations/0050_add_service_deployment_image_digest.sql +1 -0
- package/dist/server/migrations/0051_add_update_status.sql +19 -0
- package/dist/server/migrations/0052_add_notice_target.sql +2 -0
- package/dist/server/migrations/0053_colossal_sandman.sql +14 -0
- package/dist/server/migrations/0054_add_instance_smtp.sql +5 -0
- package/dist/server/migrations/0055_rainy_klaw.sql +22 -0
- package/dist/server/migrations/0056_moaning_daredevil.sql +2 -0
- package/dist/server/migrations/0057_complete_prism.sql +18 -0
- package/dist/server/migrations/0058_add_server_is_local.sql +1 -0
- package/dist/server/migrations/0059_legal_fixer.sql +18 -0
- package/dist/server/migrations/0060_add_route_strategy_host_port.sql +3 -0
- package/dist/server/migrations/0061_notification_default_multi_kind.sql +3 -0
- package/dist/server/migrations/0062_add_incoming_webhook.sql +21 -0
- package/dist/server/migrations/0063_add_migration_logs.sql +1 -0
- package/dist/server/migrations/0064_add_migration_partial.sql +2 -0
- package/dist/server/migrations/0065_custom_app_template.sql +14 -0
- package/dist/server/migrations/0066_ensure_migration_partial_columns.sql +2 -0
- package/dist/server/migrations/0067_webhook_delivery.sql +28 -0
- package/dist/server/migrations/0068_add_migration_target_volumes.sql +1 -0
- package/dist/server/migrations/0069_add_project_composite_routes.sql +1 -0
- package/dist/server/migrations/0070_forward_git_to_server.sql +1 -0
- 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/0073_project_volumes_object_storage.sql +3 -0
- package/dist/server/migrations/0074_project_compose_path.sql +1 -0
- package/dist/server/migrations/0075_service_command_argv.sql +1 -0
- package/dist/server/migrations/0076_rollback_retention.sql +17 -0
- package/dist/server/migrations/0077_domain_redirect.sql +13 -0
- package/dist/server/migrations/0078_grant_source_scope.sql +30 -0
- package/dist/server/migrations/0079_project_readiness.sql +18 -0
- package/dist/server/migrations/0080_deployment_error_classification.sql +26 -0
- package/dist/server/migrations/0081_project_readiness_repair.sql +34 -0
- package/dist/server/migrations/0082_edge_target_verification.sql +39 -0
- package/dist/server/migrations/0083_service_incident.sql +84 -0
- package/dist/server/migrations/0084_analytics_daily_rollup.sql +72 -0
- package/dist/server/migrations/0085_resource_usage.sql +68 -0
- package/dist/server/migrations/0086_remote_infra_updates.sql +41 -0
- package/dist/server/migrations/0087_server_container_version_columns.sql +17 -0
- package/dist/server/migrations/0088_audit_source_and_settings.sql +27 -0
- package/dist/server/migrations/0089_auto_scan_infra.sql +7 -0
- package/dist/server/migrations/0090_project_collect_paths.sql +18 -0
- package/dist/server/migrations/0091_project_server_id.sql +26 -0
- package/dist/server/migrations/0092_project_internal_alias.sql +13 -0
- package/dist/server/migrations/0093_service_incident_org_index.sql +13 -0
- package/dist/server/migrations/0094_backup_restore_meta.sql +15 -0
- package/dist/server/migrations/0095_backup_restore_cancel.sql +19 -0
- package/dist/server/migrations/0096_backup_policy_retention_defaults.sql +20 -0
- package/dist/server/migrations/0097_update_status_upstream_only.sql +35 -0
- package/dist/server/migrations/0098_instance_product_mode.sql +12 -0
- package/dist/server/migrations/0099_mail_webmail_project.sql +24 -0
- package/dist/server/migrations/0100_server_ssh_private_key.sql +11 -0
- package/dist/server/migrations/0101_mail_resume_step.sql +12 -0
- package/dist/server/migrations/0102_project_workload_axes.sql +19 -0
- package/dist/server/migrations/0103_dns_credential.sql +41 -0
- package/dist/server/migrations/0104_instance_host_control.sql +15 -0
- package/dist/server/migrations/0105_mail_inbound_rules.sql +80 -0
- package/dist/server/migrations/0106_mcp_call_tracking.sql +23 -0
- package/dist/server/migrations/0107_build_minute_metering_indexes.sql +20 -0
- package/dist/server/migrations/0108_credential.sql +68 -0
- package/dist/server/migrations/0109_service_build_args.sql +9 -0
- package/dist/server/migrations/0110_service_deployment_host_ports.sql +18 -0
- package/dist/server/migrations/0111_host_port_claim.sql +381 -0
- package/dist/server/migrations/0112_backup_run_execution_lease.sql +12 -0
- package/dist/server/migrations/0113_docker_migration_execution_lease.sql +11 -0
- package/dist/server/migrations/0114_build_session_execution_lease_index.sql +6 -0
- package/dist/server/migrations/0115_orphan_target_key.sql +3 -0
- package/dist/server/migrations/0116_domain_ssl_challenge.sql +2 -0
- package/dist/server/migrations/0117_github_installation_workspace_scope.sql +24 -0
- package/dist/server/migrations/0118_git_sources.sql +66 -0
- package/dist/server/migrations/0119_backup_run_batch.sql +8 -0
- package/dist/server/migrations/0120_domain_primary_unique.sql +24 -0
- package/dist/server/migrations/0121_host_port_claim_overlap.sql +14 -0
- package/dist/server/migrations/0122_data_transfer_staging.sql +45 -0
- package/dist/server/migrations/0123_drop_cloud_infra.sql +7 -0
- package/dist/server/migrations/0124_mail_dmarc_report.sql +23 -0
- package/dist/server/migrations/0125_server_security_snapshot.sql +22 -0
- package/dist/server/migrations/meta/0000_snapshot.json +4848 -0
- package/dist/server/migrations/meta/0001_snapshot.json +4991 -0
- package/dist/server/migrations/meta/0002_snapshot.json +5013 -0
- package/dist/server/migrations/meta/0003_snapshot.json +5020 -0
- package/dist/server/migrations/meta/0004_snapshot.json +5020 -0
- package/dist/server/migrations/meta/0005_snapshot.json +5039 -0
- package/dist/server/migrations/meta/0006_snapshot.json +5045 -0
- package/dist/server/migrations/meta/0007_snapshot.json +5057 -0
- package/dist/server/migrations/meta/0016_snapshot.json +6053 -0
- package/dist/server/migrations/meta/0017_snapshot.json +6091 -0
- package/dist/server/migrations/meta/0018_snapshot.json +6098 -0
- package/dist/server/migrations/meta/0019_snapshot.json +6098 -0
- package/dist/server/migrations/meta/0020_snapshot.json +6201 -0
- package/dist/server/migrations/meta/0021_snapshot.json +6213 -0
- package/dist/server/migrations/meta/0022_snapshot.json +6213 -0
- package/dist/server/migrations/meta/0023_snapshot.json +6331 -0
- package/dist/server/migrations/meta/0024_snapshot.json +6343 -0
- package/dist/server/migrations/meta/0025_snapshot.json +6350 -0
- package/dist/server/migrations/meta/0026_snapshot.json +6440 -0
- package/dist/server/migrations/meta/0027_snapshot.json +6447 -0
- package/dist/server/migrations/meta/0028_snapshot.json +6581 -0
- package/dist/server/migrations/meta/0029_snapshot.json +6710 -0
- package/dist/server/migrations/meta/0030_snapshot.json +6748 -0
- package/dist/server/migrations/meta/0031_snapshot.json +6859 -0
- package/dist/server/migrations/meta/0032_snapshot.json +7222 -0
- package/dist/server/migrations/meta/0033_snapshot.json +7249 -0
- package/dist/server/migrations/meta/0034_snapshot.json +7255 -0
- package/dist/server/migrations/meta/0035_snapshot.json +7262 -0
- package/dist/server/migrations/meta/0036_snapshot.json +7392 -0
- package/dist/server/migrations/meta/0037_snapshot.json +7602 -0
- package/dist/server/migrations/meta/0038_snapshot.json +7609 -0
- package/dist/server/migrations/meta/0039_snapshot.json +7714 -0
- package/dist/server/migrations/meta/0040_snapshot.json +7820 -0
- package/dist/server/migrations/meta/0041_snapshot.json +7833 -0
- package/dist/server/migrations/meta/0042_snapshot.json +7839 -0
- package/dist/server/migrations/meta/0043_snapshot.json +7938 -0
- package/dist/server/migrations/meta/0044_snapshot.json +7982 -0
- package/dist/server/migrations/meta/0045_snapshot.json +7989 -0
- package/dist/server/migrations/meta/0046_snapshot.json +8263 -0
- package/dist/server/migrations/meta/0047_snapshot.json +8275 -0
- package/dist/server/migrations/meta/0048_snapshot.json +8289 -0
- package/dist/server/migrations/meta/0049_snapshot.json +8308 -0
- package/dist/server/migrations/meta/0050_snapshot.json +8314 -0
- package/dist/server/migrations/meta/0051_snapshot.json +8460 -0
- package/dist/server/migrations/meta/0052_snapshot.json +8472 -0
- package/dist/server/migrations/meta/0053_snapshot.json +8556 -0
- package/dist/server/migrations/meta/0054_snapshot.json +8586 -0
- package/dist/server/migrations/meta/0055_snapshot.json +8756 -0
- package/dist/server/migrations/meta/0056_snapshot.json +8777 -0
- package/dist/server/migrations/meta/0057_snapshot.json +8904 -0
- package/dist/server/migrations/meta/0058_snapshot.json +8911 -0
- package/dist/server/migrations/meta/0059_snapshot.json +9061 -0
- package/dist/server/migrations/meta/0060_snapshot.json +9081 -0
- package/dist/server/migrations/meta/_journal.json +888 -0
- package/dist/server/pglite/pglite.data +0 -0
- package/dist/server/pglite/pglite.wasm +0 -0
- package/dist/setup-JWKZIECM.js +25 -0
- package/dist/signin-3M3UPB6K.js +667 -0
- package/dist/ssh-client-NWQVRCV7.js +29 -0
- package/dist/sso-oidc-3VDIYOEJ.js +834 -0
- package/dist/sts-B3WIYLXR.js +1426 -0
- package/dist/up-P5DMQ5YO.js +55 -0
- package/package.json +58 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
|
|
3
|
+
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
|
+
const require = __ospCreateRequire(import.meta.url);
|
|
5
|
+
import {
|
|
6
|
+
answered,
|
|
7
|
+
firewallAllowSteps,
|
|
8
|
+
firewallManager,
|
|
9
|
+
firewallPersists,
|
|
10
|
+
firewallRevokeSteps,
|
|
11
|
+
refused,
|
|
12
|
+
shellQuote
|
|
13
|
+
} from "./chunk-PVOWHIND.js";
|
|
14
|
+
|
|
15
|
+
// ../../packages/adapters/src/system/environment-ops.ts
|
|
16
|
+
function opScript(steps) {
|
|
17
|
+
return steps.join(" && ");
|
|
18
|
+
}
|
|
19
|
+
function releaseArchOf(profile) {
|
|
20
|
+
return profile.arch === "unknown" ? refused(
|
|
21
|
+
"This host's CPU architecture could not be determined, and Kraft will not default to amd64 \u2014 a release artifact for the wrong architecture installs cleanly and then fails to execute."
|
|
22
|
+
) : answered(profile.arch);
|
|
23
|
+
}
|
|
24
|
+
var HOST_STATE_DIR = "/root/.kraft";
|
|
25
|
+
var PACKAGE_NAME = /^[A-Za-z0-9][A-Za-z0-9._+@-]*$/;
|
|
26
|
+
function joinPackages(packages) {
|
|
27
|
+
if (packages.length === 0) {
|
|
28
|
+
return refused("No packages were named, so there is nothing to run.");
|
|
29
|
+
}
|
|
30
|
+
const bad = packages.find((name) => !PACKAGE_NAME.test(name));
|
|
31
|
+
if (bad !== void 0) {
|
|
32
|
+
return refused(`${JSON.stringify(bad)} is not a package name.`);
|
|
33
|
+
}
|
|
34
|
+
return answered(packages.join(" "));
|
|
35
|
+
}
|
|
36
|
+
var INSTALL = {
|
|
37
|
+
// `update` first because an install against a stale index fails on a
|
|
38
|
+
// just-provisioned box; `-qq` because this output streams into the UI.
|
|
39
|
+
apt: (names) => answered(["apt-get update -qq", `apt-get install -y -qq ${names}`]),
|
|
40
|
+
dnf: (names) => answered([`dnf install -y ${names}`]),
|
|
41
|
+
yum: (names) => answered([`yum install -y ${names}`]),
|
|
42
|
+
apk: (names) => answered([`apk add --no-cache ${names}`]),
|
|
43
|
+
brew: (names) => answered([`brew install ${names}`]),
|
|
44
|
+
none: (names) => refused(
|
|
45
|
+
`No package manager is available to install ${names} \u2014 Kraft looked for apt-get, dnf, yum, apk and brew and found none.`
|
|
46
|
+
)
|
|
47
|
+
};
|
|
48
|
+
var REMOVE = {
|
|
49
|
+
// `purge` + `autoremove`, matching what the uninstallers did before this table: a
|
|
50
|
+
// component Kraft installed should leave no config behind when removed.
|
|
51
|
+
apt: (names) => answered([`apt-get purge -y -qq ${names}`, "apt-get autoremove -y -qq"]),
|
|
52
|
+
dnf: (names) => answered([`dnf remove -y ${names}`]),
|
|
53
|
+
yum: (names) => answered([`yum remove -y ${names}`]),
|
|
54
|
+
apk: (names) => answered([`apk del ${names}`]),
|
|
55
|
+
brew: (names) => answered([`brew uninstall --force ${names}`]),
|
|
56
|
+
none: (names) => refused(`No package manager is available to remove ${names}.`)
|
|
57
|
+
};
|
|
58
|
+
var AVAILABLE_VERSION = {
|
|
59
|
+
apt: (names) => answered([`apt-cache policy ${names} 2>/dev/null`]),
|
|
60
|
+
dnf: (names) => answered([
|
|
61
|
+
`dnf -q --cacheonly list available ${names} 2>/dev/null | tail -n1`
|
|
62
|
+
]),
|
|
63
|
+
yum: (names) => answered([
|
|
64
|
+
`yum -q --cacheonly list available ${names} 2>/dev/null | tail -n1`
|
|
65
|
+
]),
|
|
66
|
+
apk: (names) => answered([`apk policy ${names} 2>/dev/null`]),
|
|
67
|
+
brew: (names) => refused(
|
|
68
|
+
`Kraft does not read Homebrew's available version for ${names} \u2014 it reports the installed version only on macOS.`
|
|
69
|
+
),
|
|
70
|
+
none: (names) => refused(
|
|
71
|
+
`No package manager is available to look up an installable version of ${names}.`
|
|
72
|
+
)
|
|
73
|
+
};
|
|
74
|
+
function noServiceManager(reason) {
|
|
75
|
+
const refuse = () => refused(reason);
|
|
76
|
+
return { enableStart: refuse, isActive: refuse };
|
|
77
|
+
}
|
|
78
|
+
var SERVICE = {
|
|
79
|
+
systemd: {
|
|
80
|
+
enableStart: (unit) => answered([`systemctl enable --now ${unit}`]),
|
|
81
|
+
// `--quiet` because the caller wants the exit code, and a unit name echoed onto
|
|
82
|
+
// stdout is the kind of thing a `!output` check reads as "running".
|
|
83
|
+
isActive: (unit) => answered([`systemctl is-active --quiet ${unit}`])
|
|
84
|
+
},
|
|
85
|
+
openrc: {
|
|
86
|
+
// Two steps, not one: `rc-update add` is persistence and `rc-service start` is now.
|
|
87
|
+
// OpenRC has no `--now`, which is why Alpine used to get a start command of
|
|
88
|
+
// `undefined` from a table that assumed systemd.
|
|
89
|
+
enableStart: (unit) => answered([`rc-update add ${unit} default`, `rc-service ${unit} start`]),
|
|
90
|
+
// Exits 0 started / 3 stopped, and prints to stdout — silenced so the contract
|
|
91
|
+
// matches systemd's `is-active --quiet`.
|
|
92
|
+
isActive: (unit) => answered([`rc-service ${unit} status >/dev/null 2>&1`])
|
|
93
|
+
},
|
|
94
|
+
launchd: noServiceManager(
|
|
95
|
+
"This host runs launchd, and Kraft does not manage macOS system services \u2014 launchd jobs are addressed by label rather than by unit name, and starting or stopping one is the operator's call."
|
|
96
|
+
),
|
|
97
|
+
none: noServiceManager(
|
|
98
|
+
"This host has no service manager Kraft can drive (no running systemd, no OpenRC, no launchd), so services cannot be started, stopped or inspected. A container started without an init system is the usual cause."
|
|
99
|
+
)
|
|
100
|
+
};
|
|
101
|
+
var GET_DOCKER_IDS = /* @__PURE__ */ new Set([
|
|
102
|
+
"ubuntu",
|
|
103
|
+
"debian",
|
|
104
|
+
"raspbian",
|
|
105
|
+
"centos",
|
|
106
|
+
"fedora",
|
|
107
|
+
"rhel",
|
|
108
|
+
"rocky"
|
|
109
|
+
]);
|
|
110
|
+
var DOCKER_CE_REPO_FILE = "/etc/yum.repos.d/docker-ce.repo";
|
|
111
|
+
function dockerCeRepoSteps(profile) {
|
|
112
|
+
const write = `curl -fsSL https://download.docker.com/linux/centos/docker-ce.repo -o ${DOCKER_CE_REPO_FILE}`;
|
|
113
|
+
const major = /^(\d+)/.exec(profile.versionId ?? "")?.[1];
|
|
114
|
+
if (!major) return [write];
|
|
115
|
+
return [write, `sed -i 's|\\$releasever|${major}|g' ${DOCKER_CE_REPO_FILE}`];
|
|
116
|
+
}
|
|
117
|
+
var DOCKER_CE_PACKAGES = "docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin";
|
|
118
|
+
var COMPOSE_PLUGIN_VERSION = "v5.4.0";
|
|
119
|
+
var COMPOSE_PLUGIN_DIR = "/usr/local/lib/docker/cli-plugins";
|
|
120
|
+
var COMPOSE_PLUGIN_PATH = `${COMPOSE_PLUGIN_DIR}/docker-compose`;
|
|
121
|
+
var COMPOSE_PLUGIN_ASSET = {
|
|
122
|
+
amd64: "x86_64",
|
|
123
|
+
arm64: "aarch64"
|
|
124
|
+
};
|
|
125
|
+
function withComposePlugin(profile, engine) {
|
|
126
|
+
const arch = releaseArchOf(profile);
|
|
127
|
+
if (!arch.supported) return arch;
|
|
128
|
+
const asset = `docker-compose-linux-${COMPOSE_PLUGIN_ASSET[arch.value]}`;
|
|
129
|
+
return answered([
|
|
130
|
+
...engine,
|
|
131
|
+
`mkdir -p ${COMPOSE_PLUGIN_DIR}`,
|
|
132
|
+
`curl -fsSL https://github.com/docker/compose/releases/download/${COMPOSE_PLUGIN_VERSION}/${asset} -o ${COMPOSE_PLUGIN_PATH}`,
|
|
133
|
+
`chmod 0755 ${COMPOSE_PLUGIN_PATH}`
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
function dockerInstallSteps(profile) {
|
|
137
|
+
if (profile.os === "darwin") {
|
|
138
|
+
return refused(
|
|
139
|
+
"Kraft does not install Docker on macOS \u2014 Docker Desktop (or OrbStack/Colima) is a GUI application an operator installs and licenses themselves."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
if (profile.os !== "linux") {
|
|
143
|
+
return refused("Docker can only be installed on a Linux or macOS host.");
|
|
144
|
+
}
|
|
145
|
+
const id = profile.distroId?.trim().toLowerCase() ?? "";
|
|
146
|
+
if (GET_DOCKER_IDS.has(id)) {
|
|
147
|
+
return answered(["curl -fsSL https://get.docker.com | sh"]);
|
|
148
|
+
}
|
|
149
|
+
switch (profile.distroFamily) {
|
|
150
|
+
case "rhel":
|
|
151
|
+
if (id === "amzn") {
|
|
152
|
+
return withComposePlugin(
|
|
153
|
+
profile,
|
|
154
|
+
profile.packageManager === "yum" ? (
|
|
155
|
+
// `amazon-linux-extras` exits 13 with "Installation failed" AFTER yum has
|
|
156
|
+
// printed "Complete!" and left dockerd on disk — seen once in four runs
|
|
157
|
+
// against a real amazonlinux:2. `opScript` joins with `&&`, so that exit
|
|
158
|
+
// aborted the plugin steps below and produced the engine-without-`docker
|
|
159
|
+
// compose` host {@link withComposePlugin} exists to prevent. Tolerate a
|
|
160
|
+
// non-zero exit only when the binary is actually there; a real failure has
|
|
161
|
+
// nothing to find and still aborts. Braced so it stays one step if a step
|
|
162
|
+
// is ever prepended — `&&` and `||` bind equally and left-associatively.
|
|
163
|
+
[
|
|
164
|
+
"{ amazon-linux-extras install -y docker || command -v docker >/dev/null 2>&1; }"
|
|
165
|
+
]
|
|
166
|
+
) : ["dnf install -y docker"]
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return answered([
|
|
170
|
+
...dockerCeRepoSteps(profile),
|
|
171
|
+
`${profile.packageManager} install -y ${DOCKER_CE_PACKAGES}`
|
|
172
|
+
]);
|
|
173
|
+
case "debian":
|
|
174
|
+
return withComposePlugin(profile, [
|
|
175
|
+
"apt-get update -qq",
|
|
176
|
+
"apt-get install -y -qq docker.io"
|
|
177
|
+
]);
|
|
178
|
+
case "alpine":
|
|
179
|
+
return answered([
|
|
180
|
+
"apk add --no-cache docker docker-cli docker-cli-compose"
|
|
181
|
+
]);
|
|
182
|
+
case "suse":
|
|
183
|
+
case "arch":
|
|
184
|
+
case "unknown":
|
|
185
|
+
return refused(
|
|
186
|
+
`Kraft has no Docker install path for this host (os-release ID=${JSON.stringify(profile.distroId ?? "")}, family ${profile.distroFamily}).`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function homeOf(profile) {
|
|
191
|
+
const home = profile.home.trim();
|
|
192
|
+
if (home) return home;
|
|
193
|
+
if (profile.isRoot) return "/root";
|
|
194
|
+
const user = profile.loginUser.trim();
|
|
195
|
+
return user ? `/home/${user}` : "/root";
|
|
196
|
+
}
|
|
197
|
+
function describeProfile(profile) {
|
|
198
|
+
const name = profile.prettyName?.trim() || profile.distroId?.trim() || profile.os;
|
|
199
|
+
const parts = [
|
|
200
|
+
name,
|
|
201
|
+
`${profile.os}/${profile.arch}`,
|
|
202
|
+
`pm=${profile.packageManager}`,
|
|
203
|
+
`init=${profile.serviceManager}`,
|
|
204
|
+
`firewall=${profile.firewall}`,
|
|
205
|
+
profile.isRoot ? "root" : profile.canSudo ? `${profile.loginUser}+sudo` : profile.loginUser
|
|
206
|
+
];
|
|
207
|
+
if (profile.isContainer) parts.push("container");
|
|
208
|
+
return parts.filter(Boolean).join(" \xB7 ");
|
|
209
|
+
}
|
|
210
|
+
function sshdEnableHintFor(profile) {
|
|
211
|
+
switch (profile.serviceManager) {
|
|
212
|
+
case "systemd":
|
|
213
|
+
return profile.distroFamily === "debian" ? "sudo systemctl enable --now ssh" : "sudo systemctl enable --now sshd";
|
|
214
|
+
case "openrc":
|
|
215
|
+
return "sudo rc-update add sshd default && sudo rc-service sshd start";
|
|
216
|
+
case "launchd":
|
|
217
|
+
return "sudo systemsetup -setremotelogin on";
|
|
218
|
+
case "none":
|
|
219
|
+
return "start this host's SSH server (no service manager was detected, so start it however this host does)";
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function hostFacts(profile) {
|
|
223
|
+
const home = homeOf(profile);
|
|
224
|
+
return {
|
|
225
|
+
profile,
|
|
226
|
+
describe: () => describeProfile(profile),
|
|
227
|
+
sshdEnableHint: () => sshdEnableHintFor(profile),
|
|
228
|
+
// Both delegate: these are facts about a `SystemFirewall`, not about a profile, and
|
|
229
|
+
// the CLI reads them off a locally-measured firewall with no profile in hand.
|
|
230
|
+
firewallManager: () => firewallManager(profile.firewall),
|
|
231
|
+
firewallPersists: () => firewallPersists(profile.firewall),
|
|
232
|
+
home: () => home,
|
|
233
|
+
// macOS has no /root to own anything, and there it is a local target rather than
|
|
234
|
+
// a provisioned server, so the invoking user's home is the only sensible anchor.
|
|
235
|
+
stateDir: () => profile.os === "darwin" ? `${home}/.kraft` : HOST_STATE_DIR,
|
|
236
|
+
scratchDir: () => `${home}/.kraft`,
|
|
237
|
+
installsNeedRoot: () => profile.os !== "darwin"
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function withPackages(packages, rule) {
|
|
241
|
+
const names = joinPackages(packages);
|
|
242
|
+
return names.supported ? rule(names.value) : names;
|
|
243
|
+
}
|
|
244
|
+
function hostCommands(profile) {
|
|
245
|
+
const pm = profile.packageManager;
|
|
246
|
+
const service = SERVICE[profile.serviceManager];
|
|
247
|
+
const unit = (name) => shellQuote(name);
|
|
248
|
+
const firewallScoped = (scope, steps) => {
|
|
249
|
+
const manager = firewallManager(profile.firewall);
|
|
250
|
+
return manager.supported ? steps(manager.value, scope) : manager;
|
|
251
|
+
};
|
|
252
|
+
return {
|
|
253
|
+
pkgInstall: (packages) => withPackages(packages, INSTALL[pm]),
|
|
254
|
+
pkgInstallVariants: (variants) => {
|
|
255
|
+
if (pm === "none") return INSTALL.none("this package");
|
|
256
|
+
const chosen = variants[pm];
|
|
257
|
+
return chosen.supported ? withPackages(chosen.value, INSTALL[pm]) : chosen;
|
|
258
|
+
},
|
|
259
|
+
pkgRemove: (packages) => withPackages(packages, REMOVE[pm]),
|
|
260
|
+
pkgAvailableVersion: (pkg) => withPackages([pkg], AVAILABLE_VERSION[pm]),
|
|
261
|
+
// Unit names are quoted rather than validated: unlike package names they are
|
|
262
|
+
// data-derived (a project slug, a unit read off a `systemctl list-units` scan), so
|
|
263
|
+
serviceEnableStart: (name) => service.enableStart(unit(name)),
|
|
264
|
+
serviceIsActive: (name) => service.isActive(unit(name)),
|
|
265
|
+
firewallAllow: (scope) => firewallScoped(scope, firewallAllowSteps),
|
|
266
|
+
firewallRevoke: (scope) => firewallScoped(scope, firewallRevokeSteps),
|
|
267
|
+
dockerInstall: () => dockerInstallSteps(profile),
|
|
268
|
+
// Through `unit()` like every other unit name, so there is one path to a service verb
|
|
269
|
+
// rather than one path plus an exception that happens to be safe today.
|
|
270
|
+
dockerStart: () => service.enableStart(unit("docker")),
|
|
271
|
+
releaseArch: () => releaseArchOf(profile)
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function mapRefusals(commands, onRefusal, gate) {
|
|
275
|
+
const out = {};
|
|
276
|
+
for (const name of Object.keys(commands)) {
|
|
277
|
+
const fn = commands[name];
|
|
278
|
+
out[name] = ((...args) => {
|
|
279
|
+
if (gate !== null) return refused(gate);
|
|
280
|
+
const answer = fn(...args);
|
|
281
|
+
return answer.supported ? answer : refused(onRefusal(answer.reason));
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
return out;
|
|
285
|
+
}
|
|
286
|
+
function hostRefusal(profile) {
|
|
287
|
+
if (profile.supported) return null;
|
|
288
|
+
const reason = profile.unsupportedReason ?? "Kraft cannot drive this host, and the detector recorded no reason.";
|
|
289
|
+
return `${reason} (host: ${describeProfile(profile)})`;
|
|
290
|
+
}
|
|
291
|
+
function envOps(profile) {
|
|
292
|
+
const facts = hostFacts(profile);
|
|
293
|
+
const label = describeProfile(profile);
|
|
294
|
+
const withHost = (reason) => `${reason} (host: ${label})`;
|
|
295
|
+
return {
|
|
296
|
+
...facts,
|
|
297
|
+
...mapRefusals(hostCommands(profile), withHost, hostRefusal(profile))
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export {
|
|
302
|
+
opScript,
|
|
303
|
+
HOST_STATE_DIR,
|
|
304
|
+
hostRefusal,
|
|
305
|
+
envOps
|
|
306
|
+
};
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
|
|
3
|
+
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
|
+
const require = __ospCreateRequire(import.meta.url);
|
|
5
|
+
import {
|
|
6
|
+
describeProcess,
|
|
7
|
+
probeListeningPort,
|
|
8
|
+
waitForPortFree
|
|
9
|
+
} from "./chunk-WYNM7L22.js";
|
|
10
|
+
import {
|
|
11
|
+
EDGE_CONTAINER_NAME,
|
|
12
|
+
classifyProxy,
|
|
13
|
+
describeContainerById,
|
|
14
|
+
isOurEdgeContainer,
|
|
15
|
+
mayStopUnitForEdgeTakeover,
|
|
16
|
+
resolveContainerPublishingPort,
|
|
17
|
+
stopContainerDurably,
|
|
18
|
+
tryExec
|
|
19
|
+
} from "./chunk-N4OALTFK.js";
|
|
20
|
+
import {
|
|
21
|
+
AppError,
|
|
22
|
+
shellQuote
|
|
23
|
+
} from "./chunk-PVOWHIND.js";
|
|
24
|
+
|
|
25
|
+
// ../../packages/adapters/src/system/proxy/detect.ts
|
|
26
|
+
var EDGE_PORTS = [80, 443];
|
|
27
|
+
var EdgeConflictError = class extends AppError {
|
|
28
|
+
constructor(status) {
|
|
29
|
+
super(
|
|
30
|
+
`Ports ${status.occupants.map((o) => o.port).join("/") || "80/443"} are in use by another service (${status.classification}). Accept a migrate or takeover to continue.`,
|
|
31
|
+
409,
|
|
32
|
+
"EDGE_CONFLICT"
|
|
33
|
+
);
|
|
34
|
+
this.status = status;
|
|
35
|
+
this.name = "EdgeConflictError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var EdgeMigrateRequested = class extends Error {
|
|
39
|
+
constructor(status, sites, warnings = []) {
|
|
40
|
+
super("Edge migration requested by user");
|
|
41
|
+
this.status = status;
|
|
42
|
+
this.sites = sites;
|
|
43
|
+
this.warnings = warnings;
|
|
44
|
+
this.name = "EdgeMigrateRequested";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var sq = shellQuote;
|
|
48
|
+
function vhostLog(message, level = "info") {
|
|
49
|
+
return { timestamp: (/* @__PURE__ */ new Date()).toISOString(), message, level };
|
|
50
|
+
}
|
|
51
|
+
async function sanitizeEdgeVhosts(executor, sitesDir, onLog) {
|
|
52
|
+
const script = [
|
|
53
|
+
`for f in ${sq(sitesDir)}/*.conf; do`,
|
|
54
|
+
// A host-side vhost may be a symlink into /etc/nginx/sites-available. That
|
|
55
|
+
// target is deliberately not mounted in the edge container, so leaving the
|
|
56
|
+
// link here makes nginx's include glob fail at startup. Materialize valid
|
|
57
|
+
// links before the container mounts this directory; remove dangling ones.
|
|
58
|
+
` [ -e "$f" ] || [ -L "$f" ] || continue;`,
|
|
59
|
+
` if [ -L "$f" ]; then`,
|
|
60
|
+
` if [ ! -e "$f" ]; then`,
|
|
61
|
+
` echo "dropped-dangling-link $f"; rm -f "$f"; continue;`,
|
|
62
|
+
` fi;`,
|
|
63
|
+
` if cat "$f" > "$f.osh-link"; then`,
|
|
64
|
+
` rm -f "$f"; mv "$f.osh-link" "$f"; echo "materialized-link $f";`,
|
|
65
|
+
` else`,
|
|
66
|
+
` rm -f "$f.osh-link"; echo "dropped-unreadable-link $f"; rm -f "$f"; continue;`,
|
|
67
|
+
` fi;`,
|
|
68
|
+
` fi;`,
|
|
69
|
+
// A real server_name is anything that isn't the `_` wildcard.
|
|
70
|
+
` if ! grep -qE '^[[:space:]]*server_name[[:space:]]+[^_;[:space:]]' "$f"; then`,
|
|
71
|
+
` echo "dropped-catchall $f"; rm -f "$f"; continue;`,
|
|
72
|
+
` fi;`,
|
|
73
|
+
` if grep -qE '[[:space:]]default_server' "$f"; then`,
|
|
74
|
+
` sed -E 's/([[:space:]]listen[^;]*)[[:space:]]+default_server/\\1/g' "$f" > "$f.osh" && mv "$f.osh" "$f" && echo "unset-default $f";`,
|
|
75
|
+
` fi;`,
|
|
76
|
+
`done`
|
|
77
|
+
].join(" ");
|
|
78
|
+
const out = await executor.exec(script).catch(() => "");
|
|
79
|
+
for (const line of out.split("\n").map((l) => l.trim()).filter(Boolean)) {
|
|
80
|
+
const [action, file] = [
|
|
81
|
+
line.slice(0, line.indexOf(" ")),
|
|
82
|
+
line.slice(line.indexOf(" ") + 1)
|
|
83
|
+
];
|
|
84
|
+
if (action === "dropped-catchall") {
|
|
85
|
+
onLog(
|
|
86
|
+
vhostLog(
|
|
87
|
+
`Dropped catch-all vhost ${file} \u2014 the edge image provides it.`,
|
|
88
|
+
"warn"
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
} else if (action === "unset-default") {
|
|
92
|
+
onLog(
|
|
93
|
+
vhostLog(
|
|
94
|
+
`Removed default_server from ${file} \u2014 the edge image owns it.`,
|
|
95
|
+
"warn"
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
} else if (action === "materialized-link") {
|
|
99
|
+
onLog(
|
|
100
|
+
vhostLog(
|
|
101
|
+
`Materialized linked edge vhost ${file} for the container mount.`,
|
|
102
|
+
"warn"
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
} else if (action === "dropped-dangling-link") {
|
|
106
|
+
onLog(vhostLog(`Dropped dangling edge vhost link ${file}.`, "warn"));
|
|
107
|
+
} else if (action === "dropped-unreadable-link") {
|
|
108
|
+
onLog(vhostLog(`Dropped unreadable edge vhost link ${file}.`, "warn"));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function edgeIsBroken(executor, container = EDGE_CONTAINER_NAME) {
|
|
113
|
+
const status = await tryExec(
|
|
114
|
+
executor,
|
|
115
|
+
`docker inspect -f '{{.State.Status}}' ${sq(container)} 2>/dev/null`
|
|
116
|
+
);
|
|
117
|
+
const state = (status ?? "").trim();
|
|
118
|
+
return state === "restarting" || state === "exited" || state === "dead";
|
|
119
|
+
}
|
|
120
|
+
async function edgeCrashReason(executor, container = EDGE_CONTAINER_NAME) {
|
|
121
|
+
const logs = await tryExec(
|
|
122
|
+
executor,
|
|
123
|
+
`docker logs --tail 40 ${sq(container)} 2>&1`
|
|
124
|
+
);
|
|
125
|
+
return logs ? edgeFailureReason(logs) : null;
|
|
126
|
+
}
|
|
127
|
+
function edgeFailureReason(containerLog) {
|
|
128
|
+
const lines = containerLog.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
129
|
+
const emerg = lines.find((l) => l.includes("[emerg]"));
|
|
130
|
+
if (emerg) return emerg.replace(/^.*\[emerg\]\s*\d*#\d*:\s*/, "");
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
async function ourEdgeContainerRunning(executor) {
|
|
134
|
+
return Boolean(await resolveOurEdgeContainer(executor));
|
|
135
|
+
}
|
|
136
|
+
var EDGE_CONTAINER_TTL_MS = 2e4;
|
|
137
|
+
var edgeContainerMemo = /* @__PURE__ */ new WeakMap();
|
|
138
|
+
var edgeMemoGeneration = 0;
|
|
139
|
+
function invalidateEdgeContainer(executor) {
|
|
140
|
+
if (executor) edgeContainerMemo.delete(executor);
|
|
141
|
+
else edgeMemoGeneration++;
|
|
142
|
+
}
|
|
143
|
+
async function resolveOurEdgeContainer(executor, opts) {
|
|
144
|
+
if (!opts?.fresh) {
|
|
145
|
+
const hit = edgeContainerMemo.get(executor);
|
|
146
|
+
if (hit && hit.generation === edgeMemoGeneration && Date.now() - hit.at < EDGE_CONTAINER_TTL_MS) {
|
|
147
|
+
return hit.value;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const resolved = await probeOurEdgeContainer(executor);
|
|
151
|
+
edgeContainerMemo.set(executor, {
|
|
152
|
+
value: resolved,
|
|
153
|
+
at: Date.now(),
|
|
154
|
+
generation: edgeMemoGeneration
|
|
155
|
+
});
|
|
156
|
+
return resolved;
|
|
157
|
+
}
|
|
158
|
+
async function detectEdgeContainer(executor) {
|
|
159
|
+
const out = await tryExec(
|
|
160
|
+
executor,
|
|
161
|
+
`docker ps -a --format '{{.Names}} {{.Image}} {{.State}}' 2>/dev/null`
|
|
162
|
+
);
|
|
163
|
+
if (out === null) return null;
|
|
164
|
+
const absent = { name: null, running: false, image: null, exists: false };
|
|
165
|
+
for (const line of out.split("\n").map((l) => l.trim()).filter(Boolean)) {
|
|
166
|
+
const [name, image, state] = line.split(" ");
|
|
167
|
+
if (!name) continue;
|
|
168
|
+
if (name === EDGE_CONTAINER_NAME || isOurEdgeContainer(name, image)) {
|
|
169
|
+
return {
|
|
170
|
+
name,
|
|
171
|
+
image: image || null,
|
|
172
|
+
running: state === "running",
|
|
173
|
+
exists: true
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return absent;
|
|
178
|
+
}
|
|
179
|
+
async function probeOurEdgeContainer(executor) {
|
|
180
|
+
const byName = await tryExec(
|
|
181
|
+
executor,
|
|
182
|
+
`docker ps --filter name=kraft-edge --format '{{.Names}}' 2>/dev/null | head -1`
|
|
183
|
+
);
|
|
184
|
+
if (byName?.trim()) return byName.trim();
|
|
185
|
+
const all = await tryExec(
|
|
186
|
+
executor,
|
|
187
|
+
`docker ps --format '{{.Names}} {{.Image}}' 2>/dev/null`
|
|
188
|
+
);
|
|
189
|
+
if (!all) return null;
|
|
190
|
+
for (const line of all.split("\n").map((l) => l.trim()).filter(Boolean)) {
|
|
191
|
+
const [name, image] = line.split(" ");
|
|
192
|
+
if (name && isOurEdgeContainer(name, image)) return name;
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
async function detectDockerOnPort(executor, port) {
|
|
197
|
+
const onPort = await resolveContainerPublishingPort(executor, port);
|
|
198
|
+
const container = onPort.kind === "one" ? onPort.container : onPort.kind === "ambiguous" ? onPort.containers[0] : null;
|
|
199
|
+
return container ? { id: container.id, name: container.name, image: container.image } : null;
|
|
200
|
+
}
|
|
201
|
+
var WORKER_RE = /\b(?:nginx|openresty)\s*:\s*worker process/i;
|
|
202
|
+
var MASTER_RE = /\b(?:nginx|openresty)\s*:\s*master process/i;
|
|
203
|
+
async function resolveProxyMaster(executor, listener) {
|
|
204
|
+
if (!listener?.pid) return listener;
|
|
205
|
+
if (!WORKER_RE.test(`${listener.rawCommand ?? ""} ${listener.command ?? ""}`))
|
|
206
|
+
return listener;
|
|
207
|
+
const ppidRaw = await tryExec(
|
|
208
|
+
executor,
|
|
209
|
+
`awk '/^PPid:/{print $2}' /proc/${listener.pid}/status 2>/dev/null || true`
|
|
210
|
+
);
|
|
211
|
+
const ppid = Number.parseInt((ppidRaw ?? "").trim(), 10);
|
|
212
|
+
if (!Number.isInteger(ppid) || ppid <= 1) return listener;
|
|
213
|
+
const master = await describeProcess(executor, ppid);
|
|
214
|
+
if (!master || !MASTER_RE.test(`${master.rawCommand ?? ""} ${master.command ?? ""}`)) {
|
|
215
|
+
return listener;
|
|
216
|
+
}
|
|
217
|
+
return master;
|
|
218
|
+
}
|
|
219
|
+
async function probeEdgePort(executor, port, ours) {
|
|
220
|
+
const listener = await resolveProxyMaster(
|
|
221
|
+
executor,
|
|
222
|
+
await probeListeningPort(executor, port)
|
|
223
|
+
);
|
|
224
|
+
const docker = await detectDockerOnPort(executor, port);
|
|
225
|
+
if (!listener && !docker) return null;
|
|
226
|
+
const cgroupContainer = !docker && listener?.containerId ? await describeContainerById(executor, listener.containerId) : null;
|
|
227
|
+
const proxy = classifyProxy(
|
|
228
|
+
[
|
|
229
|
+
docker?.image ?? cgroupContainer?.image,
|
|
230
|
+
docker?.name ?? cgroupContainer?.name,
|
|
231
|
+
listener?.rawCommand,
|
|
232
|
+
listener?.command,
|
|
233
|
+
listener?.systemdUnit
|
|
234
|
+
].filter(Boolean).join(" ")
|
|
235
|
+
);
|
|
236
|
+
const foreignDockerProxy = Boolean(docker) && !isOurEdgeContainer(docker?.name, docker?.image);
|
|
237
|
+
const managedByKraft = isOurEdgeContainer(docker?.name, docker?.image) || ours.containerRunning && !foreignDockerProxy;
|
|
238
|
+
return {
|
|
239
|
+
port,
|
|
240
|
+
pid: listener?.pid ?? void 0,
|
|
241
|
+
command: docker ? `docker container ${docker.name} (${docker.image})` : listener?.command,
|
|
242
|
+
rawCommand: listener?.rawCommand,
|
|
243
|
+
systemdUnit: listener?.systemdUnit,
|
|
244
|
+
systemdDescription: listener?.systemdDescription,
|
|
245
|
+
isDocker: Boolean(docker) || Boolean(listener?.dockerPublished) || Boolean(listener?.containerId),
|
|
246
|
+
containerName: docker?.name ?? cgroupContainer?.name,
|
|
247
|
+
// Without a container the takeover falls through to `kill -9` on a process INSIDE
|
|
248
|
+
// somebody's container, which frees nothing durably.
|
|
249
|
+
containerId: docker?.id ?? listener?.containerId,
|
|
250
|
+
dockerPublished: listener?.dockerPublished,
|
|
251
|
+
proxy,
|
|
252
|
+
managedByKraft
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
async function probeEdge(executor) {
|
|
256
|
+
const container = await resolveOurEdgeContainer(executor);
|
|
257
|
+
const containerRunning = Boolean(container) && !await edgeIsBroken(executor, container);
|
|
258
|
+
const occupants = [];
|
|
259
|
+
for (const port of EDGE_PORTS) {
|
|
260
|
+
const occ = await probeEdgePort(executor, port, { containerRunning });
|
|
261
|
+
if (occ) occupants.push(occ);
|
|
262
|
+
}
|
|
263
|
+
const foreign = occupants.filter((o) => !o.managedByKraft);
|
|
264
|
+
let classification;
|
|
265
|
+
if (occupants.length === 0) classification = "free";
|
|
266
|
+
else if (foreign.length === 0) classification = "ours";
|
|
267
|
+
else if (foreign.every((o) => o.proxy)) classification = "known";
|
|
268
|
+
else classification = "unknown";
|
|
269
|
+
return {
|
|
270
|
+
classification,
|
|
271
|
+
occupants: foreign,
|
|
272
|
+
canProceedClean: classification === "free" || classification === "ours"
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function stopTargetsForStatus(status) {
|
|
276
|
+
const out = [];
|
|
277
|
+
const seen = /* @__PURE__ */ new Set();
|
|
278
|
+
for (const o of status.occupants) {
|
|
279
|
+
const identity = o.containerName ?? o.containerId ?? o.systemdUnit ?? (o.pid ? `pid:${o.pid}` : `port:${o.port}`);
|
|
280
|
+
if (seen.has(identity)) continue;
|
|
281
|
+
seen.add(identity);
|
|
282
|
+
out.push({
|
|
283
|
+
port: o.port,
|
|
284
|
+
unit: o.systemdUnit,
|
|
285
|
+
// A forwarder's pid is dockerd's, not the workload's: killing it severs a live
|
|
286
|
+
// container's port mapping and frees nothing durably. With no container resolved
|
|
287
|
+
// there is nothing here to stop, and freeEdgeTargets reports the port still bound
|
|
288
|
+
// rather than claiming a takeover that did not happen.
|
|
289
|
+
pid: o.dockerPublished && !o.containerName && !o.containerId ? void 0 : o.pid,
|
|
290
|
+
container: o.containerName ?? o.containerId,
|
|
291
|
+
// Prefer the proxy kind over the raw cmdline — `nginx (PID 123)` reads
|
|
292
|
+
// better in "Stopping …" than `nginx: master process /usr/sbin/nginx …`.
|
|
293
|
+
label: o.proxy && o.pid ? `${o.proxy} (PID ${o.pid})` : o.command
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return out;
|
|
297
|
+
}
|
|
298
|
+
async function freeEdgeTargets(executor, targets, onLog, opts = {}) {
|
|
299
|
+
for (const t of targets) {
|
|
300
|
+
const where = t.port ? ` (port ${t.port})` : "";
|
|
301
|
+
if (t.container) {
|
|
302
|
+
onLog(`Stopping container ${t.container}${where}...`, "warn");
|
|
303
|
+
await stopContainerDurably(executor, t.container);
|
|
304
|
+
} else if (t.unit && mayStopUnitForEdgeTakeover(t.unit)) {
|
|
305
|
+
onLog(`Stopping & disabling service ${t.unit}${where}...`, "warn");
|
|
306
|
+
await tryExec(
|
|
307
|
+
executor,
|
|
308
|
+
`systemctl disable --now ${sq(t.unit)} 2>/dev/null || systemctl stop ${sq(t.unit)} 2>/dev/null || true; systemctl reset-failed ${sq(t.unit)} 2>/dev/null || true`
|
|
309
|
+
);
|
|
310
|
+
} else if (t.unit) {
|
|
311
|
+
onLog(
|
|
312
|
+
`Refusing to stop ${t.unit}${where} \u2014 free that port manually.`,
|
|
313
|
+
"error"
|
|
314
|
+
);
|
|
315
|
+
} else if (t.pid) {
|
|
316
|
+
onLog(`Stopping ${t.label ?? `process ${t.pid}`}${where}...`, "warn");
|
|
317
|
+
await tryExec(executor, `kill ${t.pid} 2>/dev/null || true`);
|
|
318
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
319
|
+
await tryExec(executor, `kill -9 ${t.pid} 2>/dev/null || true`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const named = [
|
|
323
|
+
...new Set(
|
|
324
|
+
targets.map((t) => t.port).filter((p) => typeof p === "number")
|
|
325
|
+
)
|
|
326
|
+
];
|
|
327
|
+
const stillBound = [];
|
|
328
|
+
for (const port of named.length ? named : [...EDGE_PORTS]) {
|
|
329
|
+
const { free, checked } = await waitForPortFree(executor, port, {
|
|
330
|
+
...opts.timeoutMs === void 0 ? {} : { timeoutMs: opts.timeoutMs }
|
|
331
|
+
});
|
|
332
|
+
if (!checked) {
|
|
333
|
+
onLog(
|
|
334
|
+
`Couldn't confirm port ${port} was released (socket table unreadable) \u2014 continuing.`,
|
|
335
|
+
"warn"
|
|
336
|
+
);
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (!free) {
|
|
340
|
+
stillBound.push(port);
|
|
341
|
+
onLog(`Port ${port} is STILL bound after stopping its owner.`, "error");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return { freed: stillBound.length === 0, stillBound };
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export {
|
|
348
|
+
EdgeConflictError,
|
|
349
|
+
EdgeMigrateRequested,
|
|
350
|
+
sq,
|
|
351
|
+
sanitizeEdgeVhosts,
|
|
352
|
+
edgeIsBroken,
|
|
353
|
+
edgeCrashReason,
|
|
354
|
+
edgeFailureReason,
|
|
355
|
+
ourEdgeContainerRunning,
|
|
356
|
+
invalidateEdgeContainer,
|
|
357
|
+
resolveOurEdgeContainer,
|
|
358
|
+
detectEdgeContainer,
|
|
359
|
+
probeEdge,
|
|
360
|
+
stopTargetsForStatus,
|
|
361
|
+
freeEdgeTargets
|
|
362
|
+
};
|