#!/opt/brepo/ruby33/bin/ruby # info: utility to prepare existing server with hestiacp to use bunkerweb # do not run this script n the server, where bunkerweb was installed with hestiacp # installation # options: COMMAND # # example: v-bunkerweb-migrate migrate-nginx # # Commands: # migratenginx - move old nginx configs to the new port and path # migratetobunkerweb - create items of sites in the bunkerweb database #------------------------------------------# # Variables & Functions # #------------------------------------------# # Argument definition v_command = ARGV[0] require "/usr/local/hestia/func_ruby/global_options" load_ruby_options_defaults $HESTIA = load_hestia_default_path_from_env require "main" require "modules" require "HestiaBunkerWebApi" require 'json' unless defined?(JSON) require 'fileutils' require 'time' require 'pathname' def copy_nginx_files(src_root, dest_root) FileUtils.mkdir_p(dest_root) Dir.foreach(src_root) do |entry| next if entry == '.' || entry == '..' next if entry == 'modules' || entry == 'modules-enabled' src_path = File.join(src_root, entry) dest_path = File.join(dest_root, entry) if File.directory?(src_path) FileUtils.mkdir_p(dest_path) copy_nginx_files(src_path, dest_path) else FileUtils.cp(src_path, dest_path) end end end # Function to log and execute migration stages 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." return end # Execute the stage block begin yield # Record the successful stage File.open(log_file, 'a') { |f| f.puts stage } puts "Stage #{stage} completed." rescue => e hestia_print_error_message_to_cli "Stage #{stage} failed: #{e.message}" exit 1 end end hestia_check_privileged_user load_global_bash_variables "/etc/hestiacp/hestia.conf" if $HESTIA.nil? hestia_print_error_message_to_cli "Can't find HESTIA base path" exit 1 end load_global_bash_variables "#{$HESTIA}/conf/hestia.conf" #------------------------------------------# # Verifications # #------------------------------------------# check_args 1, ARGV, "COMMAND" # Perform verification if read-only mode is enabled check_hestia_demo_mode #------------------------------------------# # Action # #------------------------------------------# case v_command.to_sym when :migratenginx log_migrate_stage('stage0') do # Create backup of /etc/nginx with timestamp timestamp = Time.now.strftime('%Y%m%d_%H%M%S') backup_root = "/etc/nginx_backup_#{timestamp}" FileUtils.mkdir_p(backup_root) src_root = '/etc/nginx' dest_root = backup_root # Custom copy function to handle symlinks in conf.d/domains def copy_with_symlinks(src, dest) Dir.foreach(src) do |entry| next if entry == '.' || entry == '..' src_path = File.join(src, entry) dest_path = File.join(dest, entry) if File.symlink?(src_path) # Check if symlink is inside conf.d/domains if src_path.include?(File.join('conf.d', 'domains')) # Resolve the target of the symlink target_path = File.readlink(src_path) # Resolve relative symlink paths unless Pathname.new(target_path).absolute? target_path = File.expand_path(target_path, File.dirname(src_path)) end if File.exist?(target_path) && File.file?(target_path) content = File.read(target_path) new_file_name = "#{entry}_content.conf" new_file_path = File.join(dest, new_file_name) File.write(new_file_path, content) end else # Preserve the symlink as is FileUtils.mkdir_p(File.dirname(dest_path)) target = File.readlink(src_path) FileUtils.ln_s(target, dest_path) end elsif File.directory?(src_path) FileUtils.mkdir_p(dest_path) copy_with_symlinks(src_path, dest_path) else FileUtils.cp(src_path, dest_path) end end end copy_with_symlinks(src_root, dest_root) end log_migrate_stage('stage1') do if $BUNKERWEB.nil? hestia_change_sys_config_value("BUNKERWEB", "yes") end end log_migrate_stage('stage2') do unless system('yum install -y nginx-system') hestia_print_error_message_to_cli "Failed to install nginx-system via yum" log_event E_ARGS, $ARGUMENTS exit 1 end end log_migrate_stage('stage3') do FileUtils.rm_f Dir.glob('/usr/local/hestia/nginx-system/etc/nginx/conf.d/*.conf') src_root = '/etc/nginx' dest_root = '/usr/local/hestia/nginx-system/etc/nginx' copy_nginx_files(src_root, dest_root) end log_migrate_stage('stage4') do # Find all files under the nginx-system directory nginx_conf_dir = '/usr/local/hestia/nginx-system/etc/nginx' Dir.glob(File.join(nginx_conf_dir, '**', '*')).each do |path| next if File.directory?(path) content = File.read(path) new_content = content.gsub(/(?:#{$PROXY_PORT} [flags]; # Matches: listen 192.168.3.81:80; or listen 192.168.3.81:80 default_server; new_content = content.gsub(/(?:#{$PROXY_SSL_PORT} ssl; if new_content == content new_content = content.gsub(/(? 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 update_module" exit 1 end end log_migrate_stage('stage8') do hestia_change_sys_config_value("PROXY_PORT", "8078") hestia_change_sys_config_value("PROXY_SSL_PORT", "8079") end #stage8 активация из запуск nginx-system log_migrate_stage('stage9') do # Delete all contents inside /etc/nginx FileUtils.rm_rf Dir.glob('/etc/nginx/*') # Stop nginx service system('systemctl stop nginx') # Start nginx-system service system('systemctl start nginx-system') end when :migratetobunkerweb #TODO настройка bunkerweb else hestia_print_error_message_to_cli "unknown command" log_event E_ARGS, $ARGUMENTS exit 1 end exit 0