package installer import ( "context" "fmt" "yizhisec.com/hsv2/forge/pkg/logger" ) func (i *installer) Prepare(ctx context.Context) error { var ( err error ) logger.Info("☑️ installer.Prepare: Starting system preparation...") // 1. Set timezone to Asia/Shanghai logger.Info("☑️ installer.Prepare: Setting timezone to Asia/Shanghai...") if err = i.setTimezone(ctx); err != nil { logger.Debug("❌ installer.Prepare: Failed to set timezone: %v", err) return fmt.Errorf("failed to set timezone: %w", err) } logger.Info("✅ installer.Prepare: Timezone set successfully") // 2. Disable swap logger.Info("☑️ installer.Prepare: Disabling swap...") if err = i.disableSwap(ctx); err != nil { logger.Debug("❌ installer.Prepare: Failed to disable swap: %v", err) return fmt.Errorf("failed to disable swap: %w", err) } logger.Info("✅ installer.Prepare: Swap disabled successfully") // 3. Load module: iscsi_tcp logger.Info("☑️ installer.Prepare: Loading kernel module iscsi_tcp...") if err = i.loadKernelModule(ctx, "iscsi_tcp"); err != nil { logger.Debug("❌ installer.Prepare: Failed to load iscsi_tcp module: %v", err) return fmt.Errorf("failed to load iscsi_tcp module: %w", err) } logger.Info("✅ installer.Prepare: iscsi_tcp module loaded successfully") // 4. Load module: br_netfilter logger.Info("☑️ installer.Prepare: Loading kernel module br_netfilter...") if err = i.loadKernelModule(ctx, "br_netfilter"); err != nil { logger.Debug("❌ installer.Prepare: Failed to load br_netfilter module: %v", err) return fmt.Errorf("failed to load br_netfilter module: %w", err) } logger.Info("✅ installer.Prepare: br_netfilter module loaded successfully") // 5. Apply sysctl settings logger.Info("☑️ installer.Prepare: Applying sysctl settings...") if err = i.applySysctlSettings(ctx); err != nil { logger.Debug("❌ installer.Prepare: Failed to apply sysctl settings: %v", err) return fmt.Errorf("failed to apply sysctl settings: %w", err) } logger.Info("✅ installer.Prepare: Sysctl settings applied successfully") logger.Info("✅ installer.Prepare: System preparation completed successfully!") return nil } // setTimezone sets the system timezone to Asia/Shanghai func (i *installer) setTimezone(ctx context.Context) error { var ( err error output string ) // Check if timezone file exists if output, err = i.ExecuteCommand(ctx, "test", "-f", "/usr/share/zoneinfo/Asia/Shanghai"); err != nil { return fmt.Errorf("failed to set timezone, err =%s, raw = %s", err.Error(), output) } // Remove old localtime link/file if output, err = i.ExecuteCommand(ctx, "rm", "-f", "/etc/localtime"); err != nil { return fmt.Errorf("failed to set timezone, err =%s, raw = %s", err.Error(), output) } // Create symlink if output, err = i.ExecuteCommand(ctx, "ln", "-s", "/usr/share/zoneinfo/Asia/Shanghai", "/etc/localtime"); err != nil { return fmt.Errorf("failed to set timezone, err =%s, raw = %s", err.Error(), output) } return nil } // disableSwap disables all swap partitions and removes swap entries from /etc/fstab func (i *installer) disableSwap(ctx context.Context) error { var ( err error output string ) // Turn off all swap if output, err = i.ExecuteCommand(ctx, "swapoff", "-a"); err != nil { logger.Debug("Failed to swapoff: %v (may be already off), raw = %s", err, output) } // Comment out swap entries in /etc/fstab to make it persistent if output, err = i.ExecuteCommand(ctx, "sed", "-i", "/swap/s/^/#/", "/etc/fstab"); err != nil { logger.Debug("Failed to comment swap in /etc/fstab: %v, raw = %s", err, output) } return nil } // loadKernelModule loads a kernel module and ensures it's loaded on boot func (i *installer) loadKernelModule(ctx context.Context, moduleName string) error { var ( err error output string ) // Load the module immediately if output, err = i.ExecuteCommand(ctx, "modprobe", moduleName); err != nil { return fmt.Errorf("failed to load module %s: %w, raw = %s", moduleName, err, output) } // Add to /etc/modules-load.d/ to load on boot filePath := fmt.Sprintf("/etc/modules-load.d/%s.conf", moduleName) command := fmt.Sprintf("echo '%s' > %s", moduleName, filePath) if output, err = i.ExecuteCommand(ctx, "bash", "-c", command); err != nil { logger.Debug("Failed to add module to modules-load.d: %v, raw = %s", err, output) } return nil } // applySysctlSettings applies required sysctl settings for Kubernetes func (i *installer) applySysctlSettings(ctx context.Context) error { var ( err error output string ) const sysctlConfig = `# Kubernetes required settings net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 net.ipv4.conf.all.forwarding = 1 net.ipv6.conf.all.forwarding = 1 vm.swappiness = 0 vm.overcommit_memory = 1 vm.panic_on_oom = 0 fs.file-max = 1000000 fs.inotify.max_user_watches = 2099999999 fs.inotify.max_user_instances = 2099999999 fs.inotify.max_queued_events = 2099999999 net.ipv4.neigh.default.gc_thresh1 = 1024 net.ipv4.neigh.default.gc_thresh2 = 4096 net.ipv4.neigh.default.gc_thresh3 = 8192 ` // Write sysctl config file command := fmt.Sprintf("cat > /etc/sysctl.d/99-kubernetes.conf << 'EOF'\n%sEOF", sysctlConfig) if output, err = i.ExecuteCommand(ctx, "bash", "-c", command); err != nil { return fmt.Errorf("failed to write sysctl config: %w, raw = %s", err, output) } // Apply sysctl settings if output, err = i.ExecuteCommand(ctx, "sysctl", "--system"); err != nil { return fmt.Errorf("failed to apply sysctl settings: %w, raw = %s", err, output) } return nil }