2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 03:07:20 +08:00

feat: postgres添加密码支持

This commit is contained in:
2026-01-24 18:48:40 +08:00
parent bbf70dd664
commit 9519be6303
6 changed files with 106 additions and 30 deletions

View File

@@ -6,6 +6,7 @@ import (
"os"
"regexp"
"github.com/acepanel/panel/pkg/types"
"github.com/go-chi/chi/v5"
"github.com/leonelquinteros/gotext"
"github.com/spf13/cast"
@@ -18,7 +19,6 @@ import (
"github.com/acepanel/panel/pkg/shell"
"github.com/acepanel/panel/pkg/systemctl"
"github.com/acepanel/panel/pkg/tools"
"github.com/acepanel/panel/pkg/types"
)
type App struct {
@@ -78,23 +78,18 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
// Load 获取负载
func (s *App) Load(w http.ResponseWriter, r *http.Request) {
rootPassword, err := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to load MySQL root password: %v", err))
return
}
if len(rootPassword) == 0 {
service.Error(w, http.StatusUnprocessableEntity, s.t.Get("MySQL root password is empty"))
return
}
status, _ := systemctl.Status("mysqld")
if !status {
service.Success(w, []types.NV{})
return
}
rootPassword, err := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to load MySQL root password: %v", err))
return
}
if err = os.Setenv("MYSQL_PWD", rootPassword); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set MYSQL_PWD env: %v", err))
return
@@ -253,6 +248,7 @@ func (s *App) SetRootPassword(w http.ResponseWriter, r *http.Request) {
return
}
}
if err = s.settingRepo.Set(biz.SettingKeyMySQLRootPassword, req.Password); err != nil {
service.Error(w, http.StatusInternalServerError, "%v", err)
return

View File

@@ -3,12 +3,15 @@ package postgresql
import (
"fmt"
"net/http"
"os"
"time"
"github.com/acepanel/panel/pkg/db"
"github.com/go-chi/chi/v5"
"github.com/leonelquinteros/gotext"
"github.com/acepanel/panel/internal/app"
"github.com/acepanel/panel/internal/biz"
"github.com/acepanel/panel/internal/service"
"github.com/acepanel/panel/pkg/io"
"github.com/acepanel/panel/pkg/shell"
@@ -17,12 +20,14 @@ import (
)
type App struct {
t *gotext.Locale
t *gotext.Locale
settingRepo biz.SettingRepo
}
func NewApp(t *gotext.Locale) *App {
func NewApp(t *gotext.Locale, setting biz.SettingRepo) *App {
return &App{
t: t,
t: t,
settingRepo: setting,
}
}
@@ -34,6 +39,8 @@ func (s *App) Route(r chi.Router) {
r.Get("/load", s.Load)
r.Get("/log", s.Log)
r.Post("/clear_log", s.ClearLog)
r.Get("/postgres_password", s.GetPostgresPassword)
r.Post("/postgres_password", s.SetPostgresPassword)
}
// GetConfig 获取配置
@@ -110,12 +117,23 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
return
}
start, err := shell.Execf(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)
postgresPassword, err := s.settingRepo.Get(biz.SettingKeyPostgresPassword)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to load PostgreSQL postgres password: %v", err))
return
}
if err = os.Setenv("PGPASSWORD", postgresPassword); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set PGPASSWORD env: %v", err))
return
}
start, err := shell.Execf(`psql -h 127.0.0.1 -U postgres -t -c "select pg_postmaster_start_time();" | head -1 | cut -d'.' -f1`)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get PostgreSQL start time: %v", err))
return
}
pid, err := shell.Execf(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
pid, err := shell.Execf(`psql -h 127.0.0.1 -U postgres -t -c "select pg_backend_pid();"`)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get PostgreSQL backend pid: %v", err))
return
@@ -125,17 +143,22 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get PostgreSQL process: %v", err))
return
}
connections, err := shell.Execf(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
connections, err := shell.Execf(`psql -h 127.0.0.1 -U postgres -t -c "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();"`)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get PostgreSQL connections: %v", err))
return
}
storage, err := shell.Execf(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)
storage, err := shell.Execf(`psql -h 127.0.0.1 -U postgres -t -c "select pg_size_pretty(pg_database_size('postgres'));"`)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get PostgreSQL database size: %v", err))
return
}
if err = os.Unsetenv("PGPASSWORD"); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to unset PGPASSWORD env: %v", err))
return
}
data := []types.NV{
{Name: s.t.Get("Start Time"), Value: start},
{Name: s.t.Get("Process PID"), Value: pid},
@@ -161,3 +184,46 @@ func (s *App) ClearLog(w http.ResponseWriter, r *http.Request) {
service.Success(w, nil)
}
// GetPostgresPassword 获取 postgres 用户密码
func (s *App) GetPostgresPassword(w http.ResponseWriter, r *http.Request) {
password, err := s.settingRepo.Get(biz.SettingKeyPostgresPassword)
if err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get postgres password: %v", err))
return
}
service.Success(w, password)
}
// SetPostgresPassword 设置 postgres 用户密码
func (s *App) SetPostgresPassword(w http.ResponseWriter, r *http.Request) {
req, err := service.Bind[SetPostgresPassword](r)
if err != nil {
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
return
}
oldPassword, _ := s.settingRepo.Get(biz.SettingKeyPostgresPassword)
postgres, err := db.NewPostgres("root", oldPassword, "127.0.0.1", 5432)
if err != nil {
// 直接修改密码
if _, err = shell.Execf(`su - postgres -c "psql -c \"ALTER USER postgres WITH PASSWORD '%s';\""`, req.Password); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set postgres password: %v", err))
return
}
} else {
defer postgres.Close()
if err = postgres.UserPassword("postgres", req.Password); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set postgres password: %v", err))
return
}
}
if err = s.settingRepo.Set(biz.SettingKeyPostgresPassword, req.Password); err != nil {
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to save postgres password: %v", err))
return
}
service.Success(w, nil)
}

View File

@@ -3,3 +3,7 @@ package postgresql
type UpdateConfig struct {
Config string `form:"config" json:"config" validate:"required"`
}
type SetPostgresPassword struct {
Password string `form:"password" json:"password" validate:"required|password"`
}

View File

@@ -21,6 +21,7 @@ const (
SettingKeyWebsiteTLSVersions SettingKey = "website_tls_versions"
SettingKeyWebsiteCipherSuites SettingKey = "website_tls_cipher_suites"
SettingKeyMySQLRootPassword SettingKey = "mysql_root_password"
SettingKeyPostgresPassword SettingKey = "postgres_password"
SettingKeyOfflineMode SettingKey = "offline_mode"
SettingKeyAutoUpdate SettingKey = "auto_update"
SettingKeyWebserver SettingKey = "webserver"

View File

@@ -531,7 +531,11 @@ func (r *backupRepo) createMySQL(name string, storage storage.Storage, target st
// createPostgres 创建 PostgreSQL 备份
func (r *backupRepo) createPostgres(name string, storage storage.Storage, target string) error {
postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
postgresPassword, err := r.setting.Get(biz.SettingKeyPostgresPassword)
if err != nil {
return err
}
postgres, err := db.NewPostgres("postgres", postgresPassword, "127.0.0.1", 5432)
if err != nil {
return err
}
@@ -553,9 +557,11 @@ func (r *backupRepo) createPostgres(name string, storage storage.Storage, target
// 导出数据库
name = name + ".sql"
if _, err = shell.Execf(`su - postgres -c "pg_dump '%s'" > '%s'`, target, filepath.Join(tmpDir, name)); err != nil {
_ = os.Setenv("PGPASSWORD", postgresPassword)
if _, err = shell.Execf(`pg_dump -h 127.0.0.1 -U postgres '%s' > '%s'`, target, filepath.Join(tmpDir, name)); err != nil {
return err
}
_ = os.Unsetenv("PGPASSWORD")
// 压缩备份文件
if err = io.Compress(tmpDir, []string{name}, filepath.Join(tmpDir, name+".zip")); err != nil {
@@ -618,9 +624,6 @@ func (r *backupRepo) restoreMySQL(backup, target string) error {
if exist, _ := mysql.DatabaseExists(target); !exist {
return errors.New(r.t.Get("database does not exist: %s", target))
}
if err = os.Setenv("MYSQL_PWD", rootPassword); err != nil {
return err
}
clean := false
if !strings.HasSuffix(backup, ".sql") {
@@ -631,12 +634,11 @@ func (r *backupRepo) restoreMySQL(backup, target string) error {
clean = true
}
_ = os.Setenv("MYSQL_PWD", rootPassword)
if _, err = shell.Execf(`mysql -u root '%s' < '%s'`, target, backup); err != nil {
return err
}
if err = os.Unsetenv("MYSQL_PWD"); err != nil {
return err
}
_ = os.Unsetenv("MYSQL_PWD")
if clean {
_ = io.Remove(filepath.Dir(backup))
}
@@ -646,7 +648,11 @@ func (r *backupRepo) restoreMySQL(backup, target string) error {
// restorePostgres 恢复 PostgreSQL 备份
func (r *backupRepo) restorePostgres(backup, target string) error {
postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
postgresPassword, err := r.setting.Get(biz.SettingKeyPostgresPassword)
if err != nil {
return err
}
postgres, err := db.NewPostgres("postgres", postgresPassword, "127.0.0.1", 5432)
if err != nil {
return err
}
@@ -664,9 +670,11 @@ func (r *backupRepo) restorePostgres(backup, target string) error {
clean = true
}
if _, err = shell.Execf(`su - postgres -c "psql '%s'" < '%s'`, target, backup); err != nil {
_ = os.Setenv("PGPASSWORD", postgresPassword)
if _, err = shell.Execf(`psql -h 127.0.0.1 -U postgres '%s' < '%s'`, target, backup); err != nil {
return err
}
_ = os.Unsetenv("PGPASSWORD")
if clean {
_ = io.Remove(filepath.Dir(backup))
}

View File

@@ -188,7 +188,8 @@ func (s *HomeService) CountInfo(w http.ResponseWriter, r *http.Request) {
}
}
if postgresqlInstalled {
postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
postgresPassword, _ := s.settingRepo.Get(biz.SettingKeyPostgresPassword)
postgres, err := db.NewPostgres("postgres", postgresPassword, "127.0.0.1", 5432)
if err == nil {
defer postgres.Close()
databases, err := postgres.Databases()