From 6ff9d6790960c5c86e81b9219424672f930f2ac6 Mon Sep 17 00:00:00 2001 From: Alexey Berezhok Date: Sat, 16 May 2026 00:10:12 +0300 Subject: [PATCH] Fixes --- bin/v-bunkerweb-migrate | 208 +++++++++++++++++++++++++++++++++++++++- func_ruby/main.rb | 8 +- 2 files changed, 208 insertions(+), 8 deletions(-) mode change 100644 => 100755 bin/v-bunkerweb-migrate diff --git a/bin/v-bunkerweb-migrate b/bin/v-bunkerweb-migrate old mode 100644 new mode 100755 index d0f4c46..246a9c6 --- a/bin/v-bunkerweb-migrate +++ b/bin/v-bunkerweb-migrate @@ -9,6 +9,7 @@ # Commands: # migratenginx - move old nginx configs to the new port and path # migratetobunkerweb - create items of sites in the bunkerweb database +# #------------------------------------------# # Variables & Functions # @@ -53,7 +54,7 @@ def log_migrate_stage(stage) log_file = '/usr/local/hestia/log/bunkerweb_migrate_stages.log' # Check if the stage has already been recorded if File.exist?(log_file) && File.readlines(log_file).any? { |line| line.strip == stage } - puts "Stage #{stage} already completed, skipping." + hestia_print_error_message_to_cli "Stage #{stage} already completed, skipping." return end # Execute the stage block @@ -61,7 +62,7 @@ def log_migrate_stage(stage) yield # Record the successful stage File.open(log_file, 'a') { |f| f.puts stage } - puts "Stage #{stage} completed." + hestia_print_error_message_to_cli "Stage #{stage} completed." rescue => e hestia_print_error_message_to_cli "Stage #{stage} failed: #{e.message}" exit 1 @@ -226,7 +227,7 @@ when :migratenginx # Write changes back if modified if modified File.open(conf_file, 'w') { |f| f.write(new_content) } - puts " Updated: #{conf_file}" + hestia_print_info_message_to_cli " Updated: #{conf_file}" end end @@ -254,7 +255,7 @@ when :migratenginx # Write changes if modified if modified File.open(default_conf, 'w') { |f| f.write(new_content) } - puts " Updated: #{default_conf}" + hestia_print_info_message_to_cli " Updated: #{default_conf}" end end end @@ -296,7 +297,204 @@ when :migratenginx system('systemctl start nginx-system') end when :migratetobunkerweb - #TODO настройка bunkerweb + log_migrate_stage('stage10') do + if system('/usr/local/hestia/bin/v-ext-modules enable bunkerweb_module') + output = IO.popen("/usr/local/hestia/bin/v-ext-modules state bunkerweb_module json").read + begin + parsed = JSON.parse(output) + if parsed.is_a?(Array) && parsed.first && parsed.first['STATE'] == 'enabled' + result = system('/usr/local/hestia/bin/v-ext-modules-run bunkerweb_module configure') + unless result + hestia_print_error_message_to_cli "bunkerweb_module configure command failed" + exit 1 + end + else + hestia_print_error_message_to_cli "bunkerweb_module not enabled after enable command" + exit 1 + end + rescue JSON::ParserError => e + hestia_print_error_message_to_cli "Failed to parse JSON from state command: #{e.message}" + exit 1 + end + else + hestia_print_error_message_to_cli "Failed to enable bunkerweb_module" + exit 1 + end + end + LIST_DOMAINS=[] + + log_migrate_stage('stage11') do + hestia_print_info_message_to_cli "Stage 11: Migrating users and domains to BunkerWeb..." + + # Get all users from HestiaCP in JSON format + user_list_output = IO.popen("/usr/local/hestia/bin/v-list-users json").read + begin + user_data = JSON.parse(user_list_output) + rescue JSON::ParserError => e + hestia_print_error_message_to_cli "Failed to parse users JSON: #{e.message}" + exit 1 + end + + # Iterate over each user + user_data.each do |username, user_info| + next unless user_info.is_a?(Hash) + + web_domains_count = user_info['U_WEB_DOMAINS'] + next unless web_domains_count && web_domains_count.to_i > 0 + + hestia_print_info_message_to_cli "Processing user: #{username} (#{web_domains_count} domains)" + + # Get web domains for this user in JSON format + domain_list_output = IO.popen("/usr/local/hestia/bin/v-list-web-domains #{username} json").read + begin + domain_data = JSON.parse(domain_list_output) + rescue JSON::ParserError => e + hestia_print_error_message_to_cli "Failed to parse domains JSON for user #{username}: #{e.message}" + next + end + + # Process each domain + domain_data.each do |domain_name, domain_info| + next unless domain_info.is_a?(Hash) + + ssl_status = domain_info['SSL'] || 'no' + is_ssl = ssl_status == 'yes' + + # Create alias list from domain info (ALIAS field contains comma-separated aliases) + raw_aliases = domain_info['ALIAS'] || '' + if raw_aliases && !raw_aliases.empty? + # Hestia uses comma-separated, pass as-is to v-bunkerweb-module (it handles conversion internally) + aliases_list = raw_aliases + else + aliases_list = domain_name # No aliases, use domain name only + end + + hestia_print_info_message_to_cli "Processing domain: #{domain_name} (SSL: #{is_ssl}, Aliases: #{aliases_list})" + + begin + # Add domain to BunkerWeb via module script (without SSL) + output = IO.popen("/usr/local/hestia/bin/v-bunkerweb-module add #{domain_name} #{$PROXY_HOST}") + hestia_print_info_message_to_cli " Added #{domain_name}: #{output.strip}" + rescue => e + hestia_print_error_message_to_cli "Failed to add domain #{domain_name} to BunkerWeb: #{e.message}" + next + end + + # Add aliases to the domain via module script + begin + output = IO.popen("/usr/local/hestia/bin/v-bunkerweb-module alias #{domain_name} \"#{aliases_list}\"") + hestia_print_info_message_to_cli " Added aliases for #{domain_name}: #{output.strip}" + rescue => e + hestia_print_error_message_to_cli "Failed to set aliases for #{domain_name}: #{e.message}" + next + end + + # Handle SSL configuration if enabled + if is_ssl + original_ssl_dir = "/home/#{username}/conf/#{domain_name}/web/ssl" + + # Check if SSL directory and files exist + unless Dir.exist?(original_ssl_dir) || File.exist?("#{original_ssl_dir}/#{domain_name}.pem") + hestia_print_error_message_to_cli "Warning: SSL files not found for #{domain_name}" + LIST_DOMAINS << { + user: username, + domain: domain_name, + is_ssl: true, + path_to_ssl: nil + } + next + end + + # Define bunkerweb directory for this domain's certificates + bunkerweb_ssl_dir = "/home/#{username}/conf/web/#{domain_name}/ssl/bunkerweb" + + begin + # Create bunkerweb SSL directory if it doesn't exist + FileUtils.mkdir_p(bunkerweb_ssl_dir) + Dir.chmod(bunkerweb_ssl_dir, 0755) + + # Define paths in bunkerweb directory + cert_path_bunkerweb = "#{bunkerweb_ssl_dir}/#{domain_name}.pem" + key_path_bunkerweb = "#{bunkerweb_ssl_dir}/#{domain_name}.key" + + # Copy all SSL files if they exist (matching v-add-web-domain-ssl behavior) + original_crt = "#{original_ssl_dir}/#{domain_name}.crt" + original_pem = "#{original_ssl_dir}/#{domain_name}.pem" + original_key = "#{original_ssl_dir}/#{domain_name}.key" + original_ca = "#{original_ssl_dir}/#{domain_name}.ca" + + # Copy .crt file if exists + if File.exist?(original_crt) + FileUtils.cp("-f", original_crt, cert_path_bunkerweb) + elsif File.exist?(original_pem) + # Only use .pem if .crt doesn't exist (fallback like the backup script) + FileUtils.cp("-f", original_pem, cert_path_bunkerweb) + end + + # Copy .key file if exists + if File.exist?(original_key) + FileUtils.cp("-f", original_key, key_path_bunkerweb) + end + + # Copy .pem file if exists (in addition to .crt for backup purposes) + if File.exist?(original_pem) + FileUtils.cp("-f", original_pem, cert_path_bunkerweb) + end + + # Copy .ca file if exists + if File.exist?(original_ca) + FileUtils.cp("-f", original_ca, "#{bunkerweb_ssl_dir}/#{domain_name}.ca") + end + + # Set ownership and permissions (nginx user can read, others cannot) + Dir.chown(bunkerweb_ssl_dir, 'root', 'nginx') + Dir.chmod(bunkerweb_ssl_dir, 0755) + + File.chown(cert_path_bunkerweb, 'root', 'nginx') if File.exist?(cert_path_bunkerweb) + File.chmod(cert_path_bunkerweb, 0640) if File.exist?(cert_path_bunkerweb) + + File.chown(key_path_bunkerweb, 'root', 'nginx') if File.exist?(key_path_bunkerweb) + File.chmod(key_path_bunkerweb, 0640) if File.exist?(key_path_bunkerweb) + + # Add SSL configuration to BunkerWeb via module script + output = IO.popen("/usr/local/hestia/bin/v-bunkerweb-module addssl #{domain_name} #{cert_path_bunkerweb} #{key_path_bunkerweb}") + hestia_print_error_message_to_cli " Added SSL for #{domain_name}: #{output.strip}" + + # Update path_to_ssl to point to bunkerweb directory + ssl_cert_path = cert_path_bunkerweb + rescue => e + hestia_print_error_message_to_cli "Failed to configure SSL for #{domain_name}: #{e.message}" + end + end + + # Populate LIST_DOMAINS array with domain info + LIST_DOMAINS << { + user: username, + domain: domain_name, + is_ssl: is_ssl, + path_to_ssl: ssl_cert_path ? ssl_cert_path : nil + } + + hestia_print_info_message_to_cli "Successfully migrated #{domain_name} for user #{username}" + end + end + + # Output the populated LIST_DOMAINS array + if !LIST_DOMAINS.empty? + hestia_print_info_message_to_cli "\n=== Populated LIST_DOMAINS ===" + LIST_DOMAINS.each_with_index do |entry, idx| + hestia_print_info_message_to_cli "#{idx + 1}. user: #{entry[:user]}, domain: #{entry[:domain]}, is_ssl: #{entry[:is_ssl].to_s}, path_to_ssl: #{entry[:path_to_ssl]}" + end + + # Output as JSON for potential use in downstream scripts + hestia_print_info_message_to_cli "\n=== LIST_DOMAINS (JSON) ===" + hestia_print_info_message_to_cli JSON.generate(LIST_DOMAINS, { indent: 2 }) + else + hestia_print_error_message_to_cli "No domains were migrated to BunkerWeb" + end + + hestia_print_info_message_to_cli "Stage 11 completed." + end else hestia_print_error_message_to_cli "unknown command" log_event E_ARGS, $ARGUMENTS diff --git a/func_ruby/main.rb b/func_ruby/main.rb index 051d5bd..77e5add 100644 --- a/func_ruby/main.rb +++ b/func_ruby/main.rb @@ -77,6 +77,10 @@ class File end end +def hestia_print_info_message_to_cli(error_message) + puts "Info: #{error_message}" +end + def hestia_print_error_message_to_cli(error_message) puts "Error: #{error_message}" end @@ -323,7 +327,7 @@ def hestia_change_sys_config_value(key, value) config_file = "/usr/local/hestia/conf/hestia.conf" if File.exist?(config_file) - File.open(config_file, File::RDWR | File::LOCK_SH) do |f| + File.open(config_file, File::RDWR) do |f| # Check if key exists in the configuration file existing_line_index = -1 @@ -343,7 +347,6 @@ def hestia_change_sys_config_value(key, value) if existing_line_index.nil? || existing_line_index == -1 # Key doesn't exist - append new line to file File.open(config_file, "a") do |append_f| - append_f.flock(File::LOCK_EX) append_f.puts("#{key}='#{value}'") end OK @@ -370,7 +373,6 @@ def hestia_change_sys_config_value(key, value) end File.open(temp_file, "w") do |output_f| - output_f.flock(File::LOCK_EX) lines.each { |l| output_f.puts(l) } end