mirror of
https://github.com/tnb-labs/panel.git
synced 2026-09-01 14:55:12 +08:00
8f226e988f
- 关闭 HTTPS 时清理 IPv6 等 SSL 监听,避免残留 ssl/quic 参数致 nginx 无法启动 - Web 服务未运行时跳过 reload,避免停止状态保存网站配置误报重载失败 - reload 失败补全 nginx -t / apachectl configtest 输出(原走 stderr 被丢弃) - 本地 MySQL 优先走 unix socket 连接,规避 skip-name-resolve 下 root@localhost 无法反解匹配 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
|
|
"github.com/acepanel/panel/v3/pkg/shell"
|
|
"github.com/acepanel/panel/v3/pkg/systemctl"
|
|
)
|
|
|
|
// MySQLResetRootPassword 重置 MySQL root密码
|
|
func MySQLResetRootPassword(password string) error {
|
|
_ = systemctl.Stop("mysqld")
|
|
if run, err := systemctl.Status("mysqld"); err != nil || run {
|
|
return fmt.Errorf("failed to stop MySQL: %w", err)
|
|
}
|
|
_, _ = shell.Execf(`systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"`)
|
|
if err := systemctl.Start("mysqld"); err != nil {
|
|
return fmt.Errorf("failed to start MySQL in safe mode: %w", err)
|
|
}
|
|
if _, err := shell.Execf(`mysql -uroot -e "FLUSH PRIVILEGES;UPDATE mysql.user SET authentication_string=null WHERE user='root' AND host='localhost';ALTER USER 'root'@'localhost' IDENTIFIED BY '%s';FLUSH PRIVILEGES;"`, password); err != nil {
|
|
return fmt.Errorf("failed to reset MySQL root password: %w", err)
|
|
}
|
|
if err := systemctl.Stop("mysqld"); err != nil {
|
|
return fmt.Errorf("failed to stop MySQL: %w", err)
|
|
}
|
|
_, _ = shell.Execf(`systemctl unset-environment MYSQLD_OPTS`)
|
|
if err := systemctl.Start("mysqld"); err != nil {
|
|
return fmt.Errorf("failed to start MySQL: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MySQLSocket 探测本地 MySQL 的 unix socket 路径
|
|
// 依次检查 /tmp/mysql.sock 及传入配置文件中的 socket 配置,均未命中返回空
|
|
func MySQLSocket(configs ...string) string {
|
|
if _, err := os.Stat("/tmp/mysql.sock"); err == nil {
|
|
return "/tmp/mysql.sock"
|
|
}
|
|
re := regexp.MustCompile(`socket\s*=\s*['"]?([^'"\s]+)`)
|
|
for _, conf := range configs {
|
|
content, err := os.ReadFile(conf)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if matches := re.FindStringSubmatch(string(content)); len(matches) > 1 {
|
|
return matches[1]
|
|
}
|
|
}
|
|
return ""
|
|
}
|