From 22227c2849784db9e1f5d4987c94673aa34095e1 Mon Sep 17 00:00:00 2001 From: Malin Date: Mon, 9 Feb 2026 13:08:03 +0100 Subject: [PATCH] fix: admpass.sh hang, OLS httpd_config structure, listener maps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes: 1. Replace admpass.sh calls with direct htpasswd writes — the script is interactive-only (no --password flag) and hangs forever in automation. Write admin htpasswd directly with openssl passwd. 2. Fix httpd_config.conf template — OLS requires virtualHost {} blocks with vhRoot/configFile, not bare include of vhconf.conf files. Add proper _backend virtualHost block, map it to Backend listener, use self-signed cert for Secure listener until real certs exist. 3. Fix addOLSListenerMap to only add maps to Default and Secure listeners (not Backend which is reserved for the admin panel). 4. Fix default PHP detection to read from wo.conf config instead of picking first installed version (which would prefer php74). Co-Authored-By: Claude Opus 4.6 --- wo/cli/plugins/secure.py | 20 ++++++++++-- wo/cli/plugins/site_functions.py | 13 +++++--- wo/cli/plugins/stack_pref.py | 48 +++++++++++++++++++---------- wo/cli/templates/ols-httpd.mustache | 23 +++++++++----- 4 files changed, 73 insertions(+), 31 deletions(-) diff --git a/wo/cli/plugins/secure.py b/wo/cli/plugins/secure.py index b824c44..c5707a7 100644 --- a/wo/cli/plugins/secure.py +++ b/wo/cli/plugins/secure.py @@ -93,13 +93,27 @@ class WOSecureController(CementBaseController): pargs.user_pass = password if password == "": pargs.user_pass = passwd - # Set OLS admin password using admpass.sh + # Set OLS admin + backend password directly + # (admpass.sh is interactive-only and hangs in automation) WOShellExec.cmd_exec( - self, "/usr/local/lsws/admin/misc/admpass.sh " - "{username} {password}" + self, "printf \"{username}:" + "$(openssl passwd -apr1 '{password}' " + "2>/dev/null)\n\" " + "> /usr/local/lsws/admin/conf/htpasswd " + "2>/dev/null" .format(username=pargs.user_input, password=pargs.user_pass), log=False) + WOShellExec.cmd_exec( + self, "printf \"{username}:" + "$(openssl passwd -apr1 '{password}' " + "2>/dev/null)\n\" " + "> {conf}/htpasswd-wo " + "2>/dev/null" + .format(username=pargs.user_input, + password=pargs.user_pass, + conf=WOVar.wo_ols_conf_dir), + log=False) WOGit.add(self, [WOVar.wo_ols_conf_dir], msg="Adding changed secure auth into Git") diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index 8c394e8..6181896 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -80,22 +80,25 @@ def addOLSVhost(self, domain, webroot): def addOLSListenerMap(self, domain): - """Add map entries for domain to listener blocks in httpd_config.conf""" + """Add map entries for domain to Default+Secure listeners in httpd_config.conf""" httpd_conf = '{0}/httpd_config.conf'.format(WOVar.wo_ols_conf_dir) - map_line = ' map {0} {0}\n'.format(domain) + map_line = ' map {0} {0}\n'.format(domain) with open(httpd_conf, 'r') as f: lines = f.readlines() new_lines = [] in_listener = False + listener_name = '' for line in lines: if line.strip().startswith('listener '): in_listener = True + listener_name = line.strip().split()[1] if in_listener and line.strip() == '}': - # Check if map for this domain already exists - if not any(domain in l and 'map' in l for l in new_lines): - new_lines.append(map_line) + # Only add maps to Default and Secure listeners (not Backend) + if listener_name in ('Default', 'Secure'): + if not any(domain in l and 'map' in l for l in new_lines): + new_lines.append(map_line) in_listener = False new_lines.append(line) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index b5564f0..3572b78 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -109,13 +109,24 @@ def post_pref(self, apt_packages, packages, upgrade=False): if not os.path.exists(ols_vhost): os.makedirs(ols_vhost) - # Determine default PHP version - default_php_short = '84' - for ver_key, ver_num in WOVar.wo_php_versions.items(): - short = ver_num.replace('.', '') - if os.path.exists('/usr/local/lsws/lsphp{0}/bin/lsphp'.format(short)): - default_php_short = short - break + # Determine default PHP version from config + try: + config_php = self.app.config.get('php', 'version') + default_php_short = config_php.replace('.', '') + except Exception: + default_php_short = '85' + # Fallback: if configured LSPHP binary doesn't exist, find one + if not os.path.exists( + '/usr/local/lsws/lsphp{0}/bin/lsphp' + .format(default_php_short)): + for ver_num in reversed( + list(WOVar.wo_php_versions.values())): + short = ver_num.replace('.', '') + if os.path.exists( + '/usr/local/lsws/lsphp{0}/bin/lsphp' + .format(short)): + default_php_short = short + break # Deploy main httpd_config.conf data = dict( @@ -181,15 +192,20 @@ def post_pref(self, apt_packages, packages, upgrade=False): .format(ngxroot))): SSL.selfsignedcert(self, proftpd=False, backend=True) - # Deploy OLS admin password via admpass.sh - if os.path.isfile('/usr/local/lsws/admin/misc/admpass.sh'): - try: - WOShellExec.cmd_exec( - self, - '/usr/local/lsws/admin/misc/admpass.sh ' - '--password "{0}"'.format(passwd)) - except CommandExecutionError as e: - Log.debug(self, "{0}".format(e)) + # Set OLS WebAdmin password directly + # (admpass.sh is interactive-only and hangs in automation) + admin_htpasswd = '/usr/local/lsws/admin/conf/htpasswd' + try: + WOShellExec.cmd_exec( + self, "printf \"admin:" + "$(openssl passwd -apr1 " + "{password} 2> /dev/null)\n\"" + "> {htpasswd} " + "2>/dev/null" + .format(password=passwd, + htpasswd=admin_htpasswd)) + except CommandExecutionError as e: + Log.debug(self, "{0}".format(e)) # traffic advice file data = dict(release=WOVar.wo_version) diff --git a/wo/cli/templates/ols-httpd.mustache b/wo/cli/templates/ols-httpd.mustache index 43ed0bd..8cb18a7 100644 --- a/wo/cli/templates/ols-httpd.mustache +++ b/wo/cli/templates/ols-httpd.mustache @@ -176,6 +176,18 @@ module cache { privateExpireInSeconds 3600 } +# Include LSPHP external app definitions +include /usr/local/lsws/conf/lsphp*.conf + +# Backend virtual host (port 22222 admin panel) +virtualHost _backend { + vhRoot /var/www/22222/ + configFile /usr/local/lsws/conf/vhosts/_backend/vhconf.conf + allowSymbolLink 1 + enableScript 1 + restrained 0 +} + # Listener for HTTP on port 80 listener Default { address *:80 @@ -186,8 +198,8 @@ listener Default { listener Secure { address *:443 secure 1 - keyFile /usr/local/lsws/conf/example.key - certFile /usr/local/lsws/conf/example.crt + keyFile /var/www/22222/cert/22222.key + certFile /var/www/22222/cert/22222.crt sslProtocol 24 enableQuic 1 } @@ -199,10 +211,7 @@ listener Backend { keyFile /var/www/22222/cert/22222.key certFile /var/www/22222/cert/22222.crt sslProtocol 24 + map _backend * } -# Include external app definitions -include /usr/local/lsws/conf/lsphp*.conf - -# Include virtual host mappings -include /usr/local/lsws/conf/vhosts/*/vhconf.conf +# WordOps managed vhost mappings below (do not edit this line)