mirror of
https://github.com/tnb-labs/panel.git
synced 2026-08-29 02:10:58 +08:00
chore: 清理代码
This commit is contained in:
@@ -42,7 +42,7 @@ func (s *App) Status() string {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/apache/conf/httpd.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/apache/conf/httpd.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -58,7 +58,7 @@ func (s *App) SaveConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/apache/conf/httpd.conf", app.Root), req.Config, 0600); err != nil {
|
||||
if err = io.Write(app.Root+"/server/apache/conf/httpd.conf", req.Config, 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package clickhouse
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -218,7 +219,7 @@ func (s *App) SetDefaultPassword(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 计算 SHA256 哈希
|
||||
hash := sha256.Sum256([]byte(req.Password))
|
||||
hexHash := fmt.Sprintf("%x", hash)
|
||||
hexHash := hex.EncodeToString(hash[:])
|
||||
|
||||
// 读取 users.d/default.yaml 并更新密码
|
||||
raw, _ := io.Read(s.usersConfigPath())
|
||||
@@ -262,12 +263,12 @@ func (s *App) SetDefaultPassword(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// configPath 返回主配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/clickhouse/config/config.yaml", app.Root)
|
||||
return app.Root + "/server/clickhouse/config/config.yaml"
|
||||
}
|
||||
|
||||
// usersConfigPath 返回用户密码配置文件路径(users.d/ 由 ConfigProcessor 自动合并到 users.yaml)
|
||||
func (s *App) usersConfigPath() string {
|
||||
return fmt.Sprintf("%s/server/clickhouse/config/users.d/default.yaml", app.Root)
|
||||
return app.Root + "/server/clickhouse/config/users.d/default.yaml"
|
||||
}
|
||||
|
||||
// getPort 从配置中获取 HTTP 端口
|
||||
|
||||
@@ -202,17 +202,17 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// configPath 返回配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/elasticsearch/config/elasticsearch.yml", app.Root)
|
||||
return app.Root + "/server/elasticsearch/config/elasticsearch.yml"
|
||||
}
|
||||
|
||||
// jvmOptionsPath 返回 JVM 选项文件路径
|
||||
func (s *App) jvmOptionsPath() string {
|
||||
return fmt.Sprintf("%s/server/elasticsearch/config/jvm.options", app.Root)
|
||||
return app.Root + "/server/elasticsearch/config/jvm.options"
|
||||
}
|
||||
|
||||
// jvmHeapOptionsPath 返回 JVM 堆内存配置文件路径(ES 9.x 推荐方式)
|
||||
func (s *App) jvmHeapOptionsPath() string {
|
||||
return fmt.Sprintf("%s/server/elasticsearch/config/jvm.options.d/heap.options", app.Root)
|
||||
return app.Root + "/server/elasticsearch/config/jvm.options.d/heap.options"
|
||||
}
|
||||
|
||||
// getPort 从配置中获取 HTTP 端口
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package fail2ban
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -126,11 +126,13 @@ func (s *App) Create(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
var ports string
|
||||
var portsSb strings.Builder
|
||||
for _, listen := range website.Listens {
|
||||
if port, err := cast.ToIntE(listen.Address); err == nil {
|
||||
ports += fmt.Sprintf("%d", port) + ","
|
||||
portsSb.WriteString(strconv.Itoa(port) + ",")
|
||||
}
|
||||
}
|
||||
ports += portsSb.String()
|
||||
ports = strings.TrimSuffix(ports, ",")
|
||||
|
||||
rule := `
|
||||
|
||||
@@ -114,18 +114,19 @@ func (s *App) UpdateUser(w http.ResponseWriter, r *http.Request) {
|
||||
hasGroup := groupRegex.MatchString(content)
|
||||
|
||||
// 替换或添加 User 和 Group 配置
|
||||
if hasUser && hasGroup {
|
||||
switch {
|
||||
case hasUser && hasGroup:
|
||||
// 两者都存在,分别替换
|
||||
content = userRegex.ReplaceAllString(content, fmt.Sprintf("User=%s", req.User))
|
||||
content = groupRegex.ReplaceAllString(content, fmt.Sprintf("Group=%s", req.Group))
|
||||
} else if hasUser && !hasGroup {
|
||||
content = userRegex.ReplaceAllString(content, "User="+req.User)
|
||||
content = groupRegex.ReplaceAllString(content, "Group="+req.Group)
|
||||
case hasUser:
|
||||
// 只有 User,替换 User 并添加 Group
|
||||
content = userRegex.ReplaceAllString(content, fmt.Sprintf("User=%s\nGroup=%s", req.User, req.Group))
|
||||
} else if !hasUser && hasGroup {
|
||||
case hasGroup:
|
||||
// 只有 Group,添加 User 并替换 Group
|
||||
content = serviceRegex.ReplaceAllString(content, fmt.Sprintf("[Service]\nUser=%s", req.User))
|
||||
content = groupRegex.ReplaceAllString(content, fmt.Sprintf("Group=%s", req.Group))
|
||||
} else {
|
||||
content = serviceRegex.ReplaceAllString(content, "[Service]\nUser="+req.User)
|
||||
content = groupRegex.ReplaceAllString(content, "Group="+req.Group)
|
||||
default:
|
||||
// 两者都不存在,在 [Service] 后添加两者
|
||||
content = serviceRegex.ReplaceAllString(content, fmt.Sprintf("[Service]\nUser=%s\nGroup=%s", req.User, req.Group))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -30,7 +29,7 @@ func (s *App) Status() string {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, _ := io.Read(fmt.Sprintf("%s/server/gitea/app.ini", app.Root))
|
||||
config, _ := io.Read(app.Root + "/server/gitea/app.ini")
|
||||
service.Success(w, config)
|
||||
}
|
||||
|
||||
@@ -41,7 +40,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/gitea/app.ini", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/gitea/app.ini", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ func (s *App) DeleteDataSource(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// configPath 返回 Grafana 主配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/grafana/conf/defaults.ini", app.Root)
|
||||
return app.Root + "/server/grafana/conf/defaults.ini"
|
||||
}
|
||||
|
||||
// getINIValue 从 INI 配置中获取指定 section 下的 key 值
|
||||
@@ -436,7 +436,7 @@ func (s *App) setINIValue(content string, section string, key string, value stri
|
||||
|
||||
// datasourcePath 返回 provisioning 数据源文件路径
|
||||
func (s *App) datasourcePath() string {
|
||||
return fmt.Sprintf("%s/server/grafana/conf/provisioning/datasources/panel.yml", app.Root)
|
||||
return app.Root + "/server/grafana/conf/provisioning/datasources/panel.yml"
|
||||
}
|
||||
|
||||
// readDatasources 读取 provisioning 文件
|
||||
|
||||
@@ -150,12 +150,12 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// configPath 返回配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/kafka/config/server.properties", app.Root)
|
||||
return app.Root + "/server/kafka/config/server.properties"
|
||||
}
|
||||
|
||||
// heapEnvPath 返回 JVM 堆内存配置文件路径
|
||||
func (s *App) heapEnvPath() string {
|
||||
return fmt.Sprintf("%s/server/kafka/config/heap.env", app.Root)
|
||||
return app.Root + "/server/kafka/config/heap.env"
|
||||
}
|
||||
|
||||
// getPropertiesValue 从 properties 内容中获取指定键的值
|
||||
|
||||
@@ -2,7 +2,6 @@ package mongodb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -240,7 +239,7 @@ func (s *App) SetAdminPassword(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// configPath 返回配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/mongodb/mongod.conf", app.Root)
|
||||
return app.Root + "/server/mongodb/mongod.conf"
|
||||
}
|
||||
|
||||
// getYAMLValue 获取嵌套 YAML 值,支持 dot notation
|
||||
|
||||
@@ -199,7 +199,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
func (s *App) SlowLog(w http.ResponseWriter, r *http.Request) {
|
||||
service.Success(w, fmt.Sprintf("%s/server/mysql/mysql-slow.log", app.Root))
|
||||
service.Success(w, app.Root+"/server/mysql/mysql-slow.log")
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
|
||||
@@ -57,7 +57,7 @@ func (s *App) Status() string {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/nginx/conf/nginx.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/nginx/conf/nginx.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -73,7 +73,7 @@ func (s *App) SaveConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/nginx/conf/nginx.conf", app.Root), req.Config, 0600); err != nil {
|
||||
if err = io.Write(app.Root+"/server/nginx/conf/nginx.conf", req.Config, 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -178,7 +178,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetConfigTune 获取 Nginx 配置调整参数
|
||||
func (s *App) GetConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/nginx/conf/nginx.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/nginx/conf/nginx.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -226,7 +226,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/nginx/conf/nginx.conf", app.Root)
|
||||
confPath := app.Root + "/server/nginx/conf/nginx.conf"
|
||||
config, err := io.Read(confPath)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package nginx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -36,7 +37,7 @@ func (s *App) CreateStreamServer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
configPath := filepath.Join(s.streamDir(), fmt.Sprintf("%s.conf", req.Name))
|
||||
configPath := filepath.Join(s.streamDir(), req.Name+".conf")
|
||||
if _, statErr := os.Stat(configPath); statErr == nil {
|
||||
service.Error(w, http.StatusConflict, s.t.Get("stream server config already exists: %s", req.Name))
|
||||
return
|
||||
@@ -70,7 +71,7 @@ func (s *App) UpdateStreamServer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
configPath := filepath.Join(s.streamDir(), fmt.Sprintf("%s.conf", name))
|
||||
configPath := filepath.Join(s.streamDir(), name+".conf")
|
||||
if _, statErr := os.Stat(configPath); os.IsNotExist(statErr) {
|
||||
service.Error(w, http.StatusNotFound, s.t.Get("stream server not found: %s", name))
|
||||
return
|
||||
@@ -78,7 +79,7 @@ func (s *App) UpdateStreamServer(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
newConfigPath := configPath
|
||||
if req.Name != name {
|
||||
newConfigPath = filepath.Join(s.streamDir(), fmt.Sprintf("%s.conf", req.Name))
|
||||
newConfigPath = filepath.Join(s.streamDir(), req.Name+".conf")
|
||||
if _, statErr := os.Stat(newConfigPath); statErr == nil {
|
||||
service.Error(w, http.StatusConflict, s.t.Get("stream server config already exists: %s", req.Name))
|
||||
return
|
||||
@@ -110,7 +111,7 @@ func (s *App) DeleteStreamServer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
configPath := filepath.Join(s.streamDir(), fmt.Sprintf("%s.conf", name))
|
||||
configPath := filepath.Join(s.streamDir(), name+".conf")
|
||||
if _, statErr := os.Stat(configPath); os.IsNotExist(statErr) {
|
||||
service.Error(w, http.StatusNotFound, s.t.Get("stream server not found: %s", name))
|
||||
return
|
||||
@@ -411,24 +412,24 @@ func (s *App) parseStreamUpstreamFile(filePath string, expectedName string) (*St
|
||||
|
||||
cfg := p.Config()
|
||||
if cfg == nil || cfg.Block == nil {
|
||||
return nil, fmt.Errorf("invalid config")
|
||||
return nil, errors.New("invalid config")
|
||||
}
|
||||
|
||||
// 查找 upstream 块
|
||||
upstreamDirectives := cfg.Block.FindDirectives("upstream")
|
||||
if len(upstreamDirectives) == 0 {
|
||||
return nil, fmt.Errorf("no upstream block found")
|
||||
return nil, errors.New("no upstream block found")
|
||||
}
|
||||
|
||||
upstreamDir := upstreamDirectives[0]
|
||||
params := upstreamDir.GetParameters()
|
||||
if len(params) == 0 {
|
||||
return nil, fmt.Errorf("upstream name not found")
|
||||
return nil, errors.New("upstream name not found")
|
||||
}
|
||||
|
||||
name := params[0].Value
|
||||
if expectedName != "" && name != expectedName {
|
||||
return nil, fmt.Errorf("upstream name mismatch")
|
||||
return nil, errors.New("upstream name mismatch")
|
||||
}
|
||||
|
||||
upstream := &StreamUpstream{
|
||||
@@ -439,7 +440,7 @@ func (s *App) parseStreamUpstreamFile(filePath string, expectedName string) (*St
|
||||
|
||||
upstreamBlock := upstreamDir.GetBlock()
|
||||
if upstreamBlock == nil {
|
||||
return nil, fmt.Errorf("upstream block is empty")
|
||||
return nil, errors.New("upstream block is empty")
|
||||
}
|
||||
|
||||
// 解析 upstream 块中的指令
|
||||
|
||||
@@ -194,11 +194,11 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/opensearch/config/opensearch.yml", app.Root)
|
||||
return app.Root + "/server/opensearch/config/opensearch.yml"
|
||||
}
|
||||
|
||||
func (s *App) jvmOptionsPath() string {
|
||||
return fmt.Sprintf("%s/server/opensearch/config/jvm.options", app.Root)
|
||||
return app.Root + "/server/opensearch/config/jvm.options"
|
||||
}
|
||||
|
||||
func (s *App) getPort() string {
|
||||
|
||||
@@ -86,12 +86,12 @@ func (s *App) Status() string {
|
||||
}
|
||||
|
||||
func (s *App) path() string {
|
||||
return fmt.Sprintf("%s/server/pgadmin", app.Root)
|
||||
return app.Root + "/server/pgadmin"
|
||||
}
|
||||
|
||||
// port 从 systemd 环境文件中解析监听端口
|
||||
func (s *App) port() (uint, error) {
|
||||
conf, err := io.Read(fmt.Sprintf("%s/pgadmin.conf", s.path()))
|
||||
conf, err := io.Read(s.path() + "/pgadmin.conf")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func (s *App) port() (uint, error) {
|
||||
|
||||
// credential 读取安装时生成的初始凭据(邮箱与密码)
|
||||
func (s *App) credential() (string, string) {
|
||||
raw, err := io.Read(fmt.Sprintf("%s/credential", s.path()))
|
||||
raw, err := io.Read(s.path() + "/credential")
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func (s *App) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
conf := fmt.Sprintf("%s/pgadmin.conf", s.path())
|
||||
conf := s.path() + "/pgadmin.conf"
|
||||
content, err := io.Read(conf)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
@@ -507,7 +507,7 @@ func (s *App) UpdateUsername(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// 更新凭据文件,下次登录按新账号重新同步
|
||||
if err = io.Write(fmt.Sprintf("%s/credential", s.path()), req.Username+"\n"+password+"\n", 0600); err != nil {
|
||||
if err = io.Write(s.path()+"/credential", req.Username+"\n"+password+"\n", 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -539,7 +539,7 @@ func (s *App) ResetPassword(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/credential", s.path()), email+"\n"+req.Password+"\n", 0600); err != nil {
|
||||
if err = io.Write(s.path()+"/credential", email+"\n"+req.Password+"\n", 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (s *App) Status() string {
|
||||
|
||||
// info 获取 phpMyAdmin 的访问目录与端口
|
||||
func (s *App) info() (string, int, error) {
|
||||
files, err := os.ReadDir(fmt.Sprintf("%s/server/phpmyadmin", app.Root))
|
||||
files, err := os.ReadDir(app.Root + "/server/phpmyadmin")
|
||||
if err != nil {
|
||||
return "", 0, errors.New(s.t.Get("phpMyAdmin directory not found"))
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (s *App) info() (string, int, error) {
|
||||
return "", 0, errors.New(s.t.Get("phpMyAdmin directory not found"))
|
||||
}
|
||||
|
||||
conf, err := io.Read(fmt.Sprintf("%s/sites/phpmyadmin/config/nginx.conf", app.Root))
|
||||
conf, err := io.Read(app.Root + "/sites/phpmyadmin/config/nginx.conf")
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
@@ -248,13 +248,13 @@ func (s *App) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
conf, err := io.Read(fmt.Sprintf("%s/sites/phpmyadmin/config/nginx.conf", app.Root))
|
||||
conf, err := io.Read(app.Root + "/sites/phpmyadmin/config/nginx.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
conf = regexp.MustCompile(`listen\s+(\d+);`).ReplaceAllString(conf, "listen "+cast.ToString(req.Port)+";")
|
||||
if err = io.Write(fmt.Sprintf("%s/sites/phpmyadmin/config/nginx.conf", app.Root), conf, 0600); err != nil {
|
||||
if err = io.Write(app.Root+"/sites/phpmyadmin/config/nginx.conf", conf, 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -282,7 +282,7 @@ func (s *App) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/sites/phpmyadmin/config/nginx.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/sites/phpmyadmin/config/nginx.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -298,7 +298,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/sites/phpmyadmin/config/nginx.conf", app.Root), req.Config, 0600); err != nil {
|
||||
if err = io.Write(app.Root+"/sites/phpmyadmin/config/nginx.conf", req.Config, 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -93,7 +92,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
// GetUserConfig 获取用户配置
|
||||
func (s *App) GetUserConfig(w http.ResponseWriter, r *http.Request) {
|
||||
// 获取配置
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/postgresql/data/pg_hba.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -110,7 +109,7 @@ func (s *App) UpdateUserConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/postgresql/data/pg_hba.conf", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -183,7 +182,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Log 获取应用日志路径列表
|
||||
func (s *App) Log(w http.ResponseWriter, r *http.Request) {
|
||||
paths, err := filepath.Glob(fmt.Sprintf("%s/server/postgresql/logs/postgresql-*.log", app.Root))
|
||||
paths, err := filepath.Glob(app.Root + "/server/postgresql/logs/postgresql-*.log")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -337,7 +336,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/postgresql/data/postgresql.conf", app.Root)
|
||||
return app.Root + "/server/postgresql/data/postgresql.conf"
|
||||
}
|
||||
|
||||
// getPort 读取 PostgreSQL 端口
|
||||
|
||||
@@ -105,7 +105,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
conf, _ := io.Read(fmt.Sprintf("%s/server/prometheus/prometheus.yml", app.Root))
|
||||
conf, _ := io.Read(app.Root + "/server/prometheus/prometheus.yml")
|
||||
service.Success(w, conf)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/prometheus/prometheus.yml", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/prometheus/prometheus.yml", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetConfigTune 获取 Prometheus 全局配置调整参数
|
||||
func (s *App) GetConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
conf, _ := io.Read(fmt.Sprintf("%s/server/prometheus/prometheus.yml", app.Root))
|
||||
conf, _ := io.Read(app.Root + "/server/prometheus/prometheus.yml")
|
||||
|
||||
var cfg struct {
|
||||
Global struct {
|
||||
@@ -159,7 +159,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/prometheus/prometheus.yml", app.Root)
|
||||
confPath := app.Root + "/server/prometheus/prometheus.yml"
|
||||
raw, _ := io.Read(confPath)
|
||||
|
||||
var cfg map[string]any
|
||||
@@ -205,7 +205,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetAlertmanagerConfig 获取 Alertmanager 配置
|
||||
func (s *App) GetAlertmanagerConfig(w http.ResponseWriter, r *http.Request) {
|
||||
conf, _ := io.Read(fmt.Sprintf("%s/server/prometheus/alertmanager/alertmanager.yml", app.Root))
|
||||
conf, _ := io.Read(app.Root + "/server/prometheus/alertmanager/alertmanager.yml")
|
||||
service.Success(w, conf)
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ func (s *App) UpdateAlertmanagerConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/prometheus/alertmanager/alertmanager.yml", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/prometheus/alertmanager/alertmanager.yml", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ func (s *App) ChangePassword(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetPort 获取端口
|
||||
func (s *App) GetPort(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/pure-ftpd/etc/pure-ftpd.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/pure-ftpd/etc/pure-ftpd.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get port: %v", err))
|
||||
return
|
||||
@@ -171,7 +171,7 @@ func (s *App) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/pure-ftpd/etc/pure-ftpd.conf", app.Root)
|
||||
confPath := app.Root + "/server/pure-ftpd/etc/pure-ftpd.conf"
|
||||
config, err := io.Read(confPath)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
@@ -206,7 +206,7 @@ func (s *App) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetConfigTune 获取 Pure-FTPd 配置调整参数
|
||||
func (s *App) GetConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/pure-ftpd/etc/pure-ftpd.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/pure-ftpd/etc/pure-ftpd.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -234,7 +234,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/pure-ftpd/etc/pure-ftpd.conf", app.Root)
|
||||
confPath := app.Root + "/server/pure-ftpd/etc/pure-ftpd.conf"
|
||||
config, err := io.Read(confPath)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -59,7 +58,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 检查 Redis 密码
|
||||
withPassword := ""
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/redis/redis.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/redis/redis.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -104,7 +103,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/redis/redis.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/redis/redis.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -120,7 +119,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/redis/redis.conf", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/redis/redis.conf", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetConfigTune 获取 Redis 配置调整参数
|
||||
func (s *App) GetConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/redis/redis.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/redis/redis.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -165,7 +164,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/redis/redis.conf", app.Root)
|
||||
confPath := app.Root + "/server/redis/redis.conf"
|
||||
config, err := io.Read(confPath)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
|
||||
@@ -175,12 +175,12 @@ func (s *App) restartServices() error {
|
||||
|
||||
// configPath 返回 broker 配置文件路径
|
||||
func (s *App) configPath() string {
|
||||
return fmt.Sprintf("%s/server/rocketmq/conf/broker.conf", app.Root)
|
||||
return app.Root + "/server/rocketmq/conf/broker.conf"
|
||||
}
|
||||
|
||||
// heapEnvPath 返回 JVM 堆内存配置文件路径
|
||||
func (s *App) heapEnvPath() string {
|
||||
return fmt.Sprintf("%s/server/rocketmq/conf/heap.env", app.Root)
|
||||
return app.Root + "/server/rocketmq/conf/heap.env"
|
||||
}
|
||||
|
||||
// getPropertiesValue 从 properties 内容中获取指定键的值
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package valkey
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -59,7 +58,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 检查 Valkey 密码
|
||||
withPassword := ""
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/valkey/valkey.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/valkey/valkey.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -104,7 +103,7 @@ func (s *App) Load(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *App) GetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/valkey/valkey.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/valkey/valkey.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -120,7 +119,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write(fmt.Sprintf("%s/server/valkey/valkey.conf", app.Root), req.Config, 0644); err != nil {
|
||||
if err = io.Write(app.Root+"/server/valkey/valkey.conf", req.Config, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func (s *App) UpdateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// GetConfigTune 获取 Valkey 配置调整参数
|
||||
func (s *App) GetConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
config, err := io.Read(fmt.Sprintf("%s/server/valkey/valkey.conf", app.Root))
|
||||
config, err := io.Read(app.Root + "/server/valkey/valkey.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -165,7 +164,7 @@ func (s *App) UpdateConfigTune(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
confPath := fmt.Sprintf("%s/server/valkey/valkey.conf", app.Root)
|
||||
confPath := app.Root + "/server/valkey/valkey.conf"
|
||||
config, err := io.Read(confPath)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
|
||||
@@ -85,8 +85,8 @@ func (uc *CertUsecase) Get(id uint) (*Cert, error) {
|
||||
return uc.repo.Get(id)
|
||||
}
|
||||
|
||||
func (uc *CertUsecase) GetByWebsite(WebsiteID uint) (*Cert, error) {
|
||||
return uc.repo.GetByWebsite(WebsiteID)
|
||||
func (uc *CertUsecase) GetByWebsite(websiteID uint) (*Cert, error) {
|
||||
return uc.repo.GetByWebsite(websiteID)
|
||||
}
|
||||
|
||||
func (uc *CertUsecase) Upload(ctx context.Context, req *request.CertUpload) (*Cert, error) {
|
||||
@@ -394,8 +394,8 @@ func (uc *CertUsecase) RefreshRenewalInfo(id uint) (mholtacme.RenewalInfo, error
|
||||
return renewInfo, nil
|
||||
}
|
||||
|
||||
func (uc *CertUsecase) Deploy(ID, WebsiteID uint, enableHTTPS bool) error {
|
||||
cert, err := uc.repo.Get(ID)
|
||||
func (uc *CertUsecase) Deploy(id, websiteID uint, enableHTTPS bool) error {
|
||||
cert, err := uc.repo.Get(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -404,7 +404,7 @@ func (uc *CertUsecase) Deploy(ID, WebsiteID uint, enableHTTPS bool) error {
|
||||
return errors.New(uc.t.Get("this certificate has not been obtained successfully and cannot be deployed"))
|
||||
}
|
||||
|
||||
website, err := uc.repo.LoadWebsite(WebsiteID)
|
||||
website, err := uc.repo.LoadWebsite(websiteID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
@@ -28,7 +27,7 @@ func containerSock(setting SettingRepo) string {
|
||||
}
|
||||
// 自动补全 scheme
|
||||
if !strings.Contains(sock, "://") {
|
||||
sock = fmt.Sprintf("unix://%s", sock)
|
||||
sock = "unix://" + sock
|
||||
}
|
||||
return sock
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
@@ -31,7 +31,7 @@ func (uc *SafeUsecase) UpdatePingStatus(ctx context.Context, status bool) error
|
||||
return err
|
||||
}
|
||||
if !running {
|
||||
return fmt.Errorf("failed to update ping status: firewall is not running")
|
||||
return errors.New("failed to update ping status: firewall is not running")
|
||||
}
|
||||
|
||||
if err = uc.repo.SetPingStatus(status); err != nil {
|
||||
|
||||
@@ -224,10 +224,10 @@ func (uc *ToolboxMigrationUsecase) pushWebsite(
|
||||
return listen.Address, !slices.Contains(listen.Args, "ssl")
|
||||
})
|
||||
create := &request.WebsiteCreate{
|
||||
Type: string(website.Type), Name: item.TargetName, Domains: website.Domains, Path: targetPath, PHP: website.PHP,
|
||||
Type: website.Type, Name: item.TargetName, Domains: website.Domains, Path: targetPath, PHP: website.PHP,
|
||||
Listens: lo.Ternary(len(listens) > 0, listens, []string{"80"}),
|
||||
}
|
||||
if string(website.Type) == "proxy" && len(website.Proxies) > 0 {
|
||||
if website.Type == "proxy" && len(website.Proxies) > 0 {
|
||||
create.Proxy = website.Proxies[0].Pass
|
||||
}
|
||||
if _, err = uc.remote.Request(ctx, conn, "POST", "/api/website", create); err != nil {
|
||||
|
||||
@@ -3,7 +3,6 @@ package biz
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
@@ -147,7 +146,7 @@ func (uc *WebsiteUsecase) Create(ctx context.Context, req *request.WebsiteCreate
|
||||
Username: req.DBUser,
|
||||
Password: req.DBPassword,
|
||||
Host: "localhost",
|
||||
Comment: fmt.Sprintf("website %s", req.Name),
|
||||
Comment: "website " + req.Name,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-10
@@ -544,7 +544,7 @@ func (r *backupRepo) createWebsite(name string, storage storage.Storage, target
|
||||
}
|
||||
|
||||
// 压缩网站
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
if err = io.Compress(website.Path, nil, filepath.Join(tmpDir, name)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -594,7 +594,7 @@ func (r *backupRepo) createMySQL(name string, storage storage.Storage, target st
|
||||
}
|
||||
|
||||
// 导出数据库
|
||||
name = name + ".sql"
|
||||
name += ".sql"
|
||||
_ = os.Setenv("MYSQL_PWD", rootPassword)
|
||||
if _, err = shell.Execf(`mysqldump -u root --single-transaction --quick '%s' > '%s'`, target, filepath.Join(tmpDir, name)); err != nil {
|
||||
return err
|
||||
@@ -607,7 +607,7 @@ func (r *backupRepo) createMySQL(name string, storage storage.Storage, target st
|
||||
}
|
||||
|
||||
// 上传备份文件到存储器
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
file, err := os.Open(filepath.Join(tmpDir, name))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -652,7 +652,7 @@ func (r *backupRepo) createPostgres(name string, storage storage.Storage, target
|
||||
}
|
||||
|
||||
// 导出数据库
|
||||
name = name + ".sql"
|
||||
name += ".sql"
|
||||
_ = 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
|
||||
@@ -665,7 +665,7 @@ func (r *backupRepo) createPostgres(name string, storage storage.Storage, target
|
||||
}
|
||||
|
||||
// 上传备份文件到存储器
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
file, err := os.Open(filepath.Join(tmpDir, name))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -734,7 +734,7 @@ func (r *backupRepo) createClickHouse(name string, storage storage.Storage, targ
|
||||
}
|
||||
stmt := strings.TrimSpace(create)
|
||||
stmt = strings.ReplaceAll(stmt, fmt.Sprintf("`%s`.", target), "")
|
||||
stmt = strings.ReplaceAll(stmt, fmt.Sprintf("%s.", target), "")
|
||||
stmt = strings.ReplaceAll(stmt, target+".", "")
|
||||
schema.WriteString(stmt)
|
||||
schema.WriteString(";\n")
|
||||
}
|
||||
@@ -753,7 +753,7 @@ func (r *backupRepo) createClickHouse(name string, storage storage.Storage, targ
|
||||
}
|
||||
|
||||
// 压缩备份文件
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
if err = io.Compress(tmpDir, files, filepath.Join(tmpDir, name)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -817,7 +817,7 @@ func (r *backupRepo) createPath(name string, storage storage.Storage, target str
|
||||
}
|
||||
|
||||
// 压缩目录
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
if err = io.Compress(target, nil, filepath.Join(tmpDir, name)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1185,7 +1185,7 @@ func (r *backupRepo) createRedisLike(name string, storage storage.Storage, kind
|
||||
}
|
||||
|
||||
// 压缩备份文件
|
||||
name = name + r.backupExt()
|
||||
name += r.backupExt()
|
||||
if err = io.Compress(tmpDir, []string{"dump.rdb"}, filepath.Join(tmpDir, name)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1697,7 +1697,7 @@ func (r *backupRepo) FixPanel() error {
|
||||
if err = io.Remove(filepath.Join(app.Root, "panel")); err != nil {
|
||||
return errors.New(r.t.Get("Remove panel file failed: %v", err))
|
||||
}
|
||||
if err = io.Mv(filepath.Join("/tmp/panel-fix", "panel"), filepath.Join(app.Root)); err != nil {
|
||||
if err = io.Mv(filepath.Join("/tmp/panel-fix", "panel"), filepath.Clean(app.Root)); err != nil {
|
||||
return errors.New(r.t.Get("Move panel file failed: %v", err))
|
||||
}
|
||||
if io.Exists(keep) {
|
||||
|
||||
@@ -72,9 +72,9 @@ func (r *certRepo) List(page, limit uint) ([]*types.CertList, int64, error) {
|
||||
item.Issuer = decode.Issuer.CommonName
|
||||
item.OCSPServer = decode.OCSPServer
|
||||
// 合并 DNSNames 和 IPAddresses
|
||||
item.DNSNames = append(decode.DNSNames, lo.Map(decode.IPAddresses, func(ip net.IP, _ int) string {
|
||||
item.DNSNames = slices.Concat(decode.DNSNames, lo.Map(decode.IPAddresses, func(ip net.IP, _ int) string {
|
||||
return ip.String()
|
||||
})...)
|
||||
}))
|
||||
}
|
||||
return item
|
||||
})
|
||||
@@ -88,9 +88,9 @@ func (r *certRepo) Get(id uint) (*biz.Cert, error) {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
func (r *certRepo) GetByWebsite(WebsiteID uint) (*biz.Cert, error) {
|
||||
func (r *certRepo) GetByWebsite(websiteID uint) (*biz.Cert, error) {
|
||||
cert := new(biz.Cert)
|
||||
err := r.db.Model(&biz.Cert{}).Preload("Website").Preload("Account").Preload("DNS").Where("website_id = ?", WebsiteID).First(cert).Error
|
||||
err := r.db.Model(&biz.Cert{}).Preload("Website").Preload("Account").Preload("DNS").Where("website_id = ?", websiteID).First(cert).Error
|
||||
return cert, err
|
||||
}
|
||||
|
||||
@@ -166,9 +166,9 @@ func (r *certRepo) ObtainPanel(account *biz.CertAccount, names []string, webServ
|
||||
}
|
||||
|
||||
// LoadWebsite 根据 ID 加载网站
|
||||
func (r *certRepo) LoadWebsite(WebsiteID uint) (*biz.Website, error) {
|
||||
func (r *certRepo) LoadWebsite(websiteID uint) (*biz.Website, error) {
|
||||
website := new(biz.Website)
|
||||
if err := r.db.Where("id", WebsiteID).First(website).Error; err != nil {
|
||||
if err := r.db.Where("id", websiteID).First(website).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return website, nil
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"slices"
|
||||
@@ -239,7 +240,7 @@ func (r *containerRepo) Create(sock string, req *request.ContainerCreate) (strin
|
||||
return "", fmt.Errorf("container port and host port count do not match (container: %d host: %d)", port.ContainerStart-port.ContainerEnd, port.HostStart-port.HostEnd)
|
||||
}
|
||||
if port.ContainerStart > port.ContainerEnd || port.HostStart > port.HostEnd || port.ContainerStart < 1 || port.HostStart < 1 {
|
||||
return "", fmt.Errorf("port range is invalid")
|
||||
return "", errors.New("port range is invalid")
|
||||
}
|
||||
|
||||
count := uint(0)
|
||||
|
||||
@@ -71,8 +71,8 @@ func (r *cronRepo) Delete(cron *biz.Cron) error {
|
||||
|
||||
// WriteNewScript 生成随机脚本文件并返回脚本与日志路径
|
||||
func (r *cronRepo) WriteNewScript(script string) (string, string, error) {
|
||||
shellDir := fmt.Sprintf("%s/server/cron/", app.Root)
|
||||
shellLogDir := fmt.Sprintf("%s/server/cron/logs/", app.Root)
|
||||
shellDir := app.Root + "/server/cron/"
|
||||
shellLogDir := app.Root + "/server/cron/logs/"
|
||||
shellFile := str.Random(16)
|
||||
if err := io.Write(filepath.Join(shellDir, shellFile+".sh"), script, 0700); err != nil {
|
||||
return "", "", errors.New(err.Error())
|
||||
|
||||
@@ -129,7 +129,7 @@ func (r *projectRepo) Delete(project *biz.Project) error {
|
||||
|
||||
// unitFilePath 返回 systemd unit 文件路径
|
||||
func (r *projectRepo) unitFilePath(name string) string {
|
||||
return filepath.Join("/etc/systemd/system", fmt.Sprintf("%s.service", name))
|
||||
return filepath.Join("/etc/systemd/system", name+".service")
|
||||
}
|
||||
|
||||
// ParseDetail 从数据库记录和 systemd unit 文件解析项目详情
|
||||
|
||||
@@ -112,7 +112,7 @@ func (a *baotaAdapter) websiteItems(ctx context.Context) ([]types.MigrationItem,
|
||||
continue
|
||||
}
|
||||
// PHP / WP2 为 PHP 站点,HTML 为静态站点,Proxy 为反代站点,其余是项目
|
||||
subtype := ""
|
||||
var subtype string
|
||||
switch strings.ToLower(cast.ToString(row["project_type"])) {
|
||||
case "php", "wp2":
|
||||
subtype = lo.Ternary(cast.ToString(row["php_version"]) == "静态", "static", "php")
|
||||
|
||||
@@ -201,20 +201,3 @@ func (r *userRepo) UpdateTwoFA(id uint, code, secret string) error {
|
||||
user.TwoFA = secret
|
||||
return r.db.Save(user).Error
|
||||
}
|
||||
|
||||
func (r *userRepo) CheckTwoFA(id uint, code string) (bool, error) {
|
||||
user, err := r.Get(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if user.TwoFA == "" {
|
||||
return true, nil // 未开启2FA,无需验证
|
||||
}
|
||||
|
||||
if valid := totp.Validate(code, user.TwoFA); !valid {
|
||||
return false, errors.New(r.t.Get("invalid 2FA code"))
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ func (r *webhookRepo) Call(key string) (string, error) {
|
||||
if webhook.User == "" || webhook.User == "root" {
|
||||
cmd = exec.Command("bash", scriptFile)
|
||||
} else {
|
||||
cmd = exec.Command("su", "-s", "/bin/bash", "-c", fmt.Sprintf("bash %s", scriptFile), webhook.User)
|
||||
cmd = exec.Command("su", "-s", "/bin/bash", "-c", "bash "+scriptFile, webhook.User)
|
||||
}
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
@@ -921,11 +921,9 @@ func (r *websiteRepo) applyUpdate(req *request.WebsiteUpdate, website *biz.Websi
|
||||
}
|
||||
}
|
||||
_, _ = shell.Execf(`chattr +i '%s'`, userIni)
|
||||
} else {
|
||||
if io.Exists(userIni) {
|
||||
if err = io.Remove(userIni); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if io.Exists(userIni) {
|
||||
if err = io.Remove(userIni); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@ func MustInstall(t *gotext.Locale, app biz.AppRepo) func(next http.Handler) http
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var slugs []string
|
||||
if strings.HasPrefix(r.URL.Path, "/api/website") {
|
||||
switch {
|
||||
case strings.HasPrefix(r.URL.Path, "/api/website"):
|
||||
slugs = append(slugs, "nginx", "openresty", "apache", "openlitespeed", "caddy")
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/container") {
|
||||
case strings.HasPrefix(r.URL.Path, "/api/container"):
|
||||
slugs = append(slugs, "podman", "docker")
|
||||
} else if strings.HasPrefix(r.URL.Path, "/api/apps/") {
|
||||
case strings.HasPrefix(r.URL.Path, "/api/apps/"):
|
||||
pathArr := strings.Split(r.URL.Path, "/")
|
||||
if len(pathArr) < 4 {
|
||||
Abort(w, http.StatusForbidden, t.Get("app not found"))
|
||||
|
||||
@@ -34,7 +34,7 @@ func MustLogin(t *gotext.Locale, conf *config.Config, session *sessions.Manager,
|
||||
return
|
||||
}
|
||||
|
||||
userID := uint(0)
|
||||
var userID uint
|
||||
if r.Header.Get("Authorization") != "" {
|
||||
// 禁止访问 ws 相关的接口
|
||||
if strings.HasPrefix(r.URL.Path, "/api/ws") {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/libtnb/validator"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -36,9 +34,9 @@ func (r *Exists) Passes(f validator.Field) bool {
|
||||
tableName := args[0]
|
||||
fieldNames := args[1:]
|
||||
|
||||
query := r.db.Table(tableName).Where(fmt.Sprintf("%s = ?", fieldNames[0]), val)
|
||||
query := r.db.Table(tableName).Where(fieldNames[0]+" = ?", val)
|
||||
for _, fieldName := range fieldNames[1:] {
|
||||
query = query.Or(fmt.Sprintf("%s = ?", fieldName), val)
|
||||
query = query.Or(fieldName+" = ?", val)
|
||||
}
|
||||
|
||||
var count int64
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/libtnb/validator"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -36,9 +34,9 @@ func (r *NotExists) Passes(f validator.Field) bool {
|
||||
tableName := args[0]
|
||||
fieldNames := args[1:]
|
||||
|
||||
query := r.db.Table(tableName).Where(fmt.Sprintf("%s = ?", fieldNames[0]), val)
|
||||
query := r.db.Table(tableName).Where(fieldNames[0]+" = ?", val)
|
||||
for _, fieldName := range fieldNames[1:] {
|
||||
query = query.Or(fmt.Sprintf("%s = ?", fieldName), val)
|
||||
query = query.Or(fieldName+" = ?", val)
|
||||
}
|
||||
|
||||
var count int64
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -44,7 +45,7 @@ func (s *EnvironmentPHPService) SetCli(w http.ResponseWriter, r *http.Request) {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -64,7 +65,7 @@ func (s *EnvironmentPHPService) PHPInfo(w http.ResponseWriter, r *http.Request)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -85,7 +86,7 @@ func (s *EnvironmentPHPService) GetConfig(w http.ResponseWriter, r *http.Request
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -105,7 +106,7 @@ func (s *EnvironmentPHPService) UpdateConfig(w http.ResponseWriter, r *http.Requ
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -124,7 +125,7 @@ func (s *EnvironmentPHPService) GetFPMConfig(w http.ResponseWriter, r *http.Requ
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -144,7 +145,7 @@ func (s *EnvironmentPHPService) UpdateFPMConfig(w http.ResponseWriter, r *http.R
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -163,7 +164,7 @@ func (s *EnvironmentPHPService) Load(w http.ResponseWriter, r *http.Request) {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -228,7 +229,7 @@ func (s *EnvironmentPHPService) Log(w http.ResponseWriter, r *http.Request) {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -242,7 +243,7 @@ func (s *EnvironmentPHPService) SlowLog(w http.ResponseWriter, r *http.Request)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -256,7 +257,7 @@ func (s *EnvironmentPHPService) ModuleList(w http.ResponseWriter, r *http.Reques
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -289,7 +290,7 @@ func (s *EnvironmentPHPService) InstallModule(w http.ResponseWriter, r *http.Req
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -324,7 +325,7 @@ func (s *EnvironmentPHPService) UninstallModule(w http.ResponseWriter, r *http.R
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -607,7 +608,7 @@ func (s *EnvironmentPHPService) GetConfigTune(w http.ResponseWriter, r *http.Req
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -666,7 +667,7 @@ func (s *EnvironmentPHPService) UpdateConfigTune(w http.ResponseWriter, r *http.
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
@@ -729,7 +730,7 @@ func (s *EnvironmentPHPService) CleanSession(w http.ResponseWriter, r *http.Requ
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
if !s.environmentRepo.IsInstalled("php", fmt.Sprintf("%d", req.Version)) {
|
||||
if !s.environmentRepo.IsInstalled("php", strconv.FormatUint(uint64(req.Version), 10)) {
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("PHP-%d is not installed", req.Version))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package service
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmp"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
@@ -682,38 +683,23 @@ func (s *FileService) List(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
var cmp int
|
||||
var order int
|
||||
switch sortKey {
|
||||
case "size":
|
||||
// 按大小排序
|
||||
if a.info.Size() < b.info.Size() {
|
||||
cmp = -1
|
||||
} else if a.info.Size() > b.info.Size() {
|
||||
cmp = 1
|
||||
} else {
|
||||
cmp = 0
|
||||
}
|
||||
order = cmp.Compare(a.info.Size(), b.info.Size())
|
||||
case "modify":
|
||||
// 按修改时间排序
|
||||
if a.info.ModTime().Before(b.info.ModTime()) {
|
||||
cmp = -1
|
||||
} else if a.info.ModTime().After(b.info.ModTime()) {
|
||||
cmp = 1
|
||||
} else {
|
||||
cmp = 0
|
||||
}
|
||||
case "name":
|
||||
// 按名称排序
|
||||
cmp = strings.Compare(strings.ToLower(a.info.Name()), strings.ToLower(b.info.Name()))
|
||||
order = a.info.ModTime().Compare(b.info.ModTime())
|
||||
default:
|
||||
// 默认按名称排序
|
||||
cmp = strings.Compare(strings.ToLower(a.info.Name()), strings.ToLower(b.info.Name()))
|
||||
order = strings.Compare(strings.ToLower(a.info.Name()), strings.ToLower(b.info.Name()))
|
||||
}
|
||||
|
||||
if sortDesc {
|
||||
cmp = -cmp
|
||||
order = -order
|
||||
}
|
||||
return cmp
|
||||
return order
|
||||
})
|
||||
|
||||
// 转换回 DirEntry 列表
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
@@ -25,7 +26,7 @@ func TestClientIP(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
r := httptest.NewRequest("POST", "/api/user/login", nil)
|
||||
r := httptest.NewRequest(http.MethodPost, "/api/user/login", nil)
|
||||
r.RemoteAddr = c.remoteAddr
|
||||
if c.value != "" {
|
||||
r.Header.Set(c.header, c.value)
|
||||
|
||||
@@ -232,32 +232,32 @@ func (s *HomeService) InstalledEnvironment(w http.ResponseWriter, r *http.Reques
|
||||
|
||||
// Go 版本
|
||||
goData := lo.Map(s.environmentRepo.InstalledSlugs("go"), func(slug string, _ int) types.LV {
|
||||
return types.LV{Value: slug, Label: fmt.Sprintf("Go %s", s.environmentRepo.InstalledVersion("go", slug))}
|
||||
return types.LV{Value: slug, Label: "Go " + s.environmentRepo.InstalledVersion("go", slug)}
|
||||
})
|
||||
|
||||
// Java 版本
|
||||
javaData := lo.Map(s.environmentRepo.InstalledSlugs("java"), func(slug string, _ int) types.LV {
|
||||
return types.LV{Value: slug, Label: fmt.Sprintf("Java %s", s.environmentRepo.InstalledVersion("java", slug))}
|
||||
return types.LV{Value: slug, Label: "Java " + s.environmentRepo.InstalledVersion("java", slug)}
|
||||
})
|
||||
|
||||
// Node.js 版本
|
||||
nodejsData := lo.Map(s.environmentRepo.InstalledSlugs("nodejs"), func(slug string, _ int) types.LV {
|
||||
return types.LV{Value: slug, Label: fmt.Sprintf("Node.js %s", s.environmentRepo.InstalledVersion("nodejs", slug))}
|
||||
return types.LV{Value: slug, Label: "Node.js " + s.environmentRepo.InstalledVersion("nodejs", slug)}
|
||||
})
|
||||
|
||||
// PHP 版本
|
||||
phpData := lo.Map(s.environmentRepo.InstalledSlugs("php"), func(slug string, _ int) types.LVInt {
|
||||
return types.LVInt{Value: cast.ToInt(slug), Label: fmt.Sprintf("PHP %s", s.environmentRepo.InstalledVersion("php", slug))}
|
||||
return types.LVInt{Value: cast.ToInt(slug), Label: "PHP " + s.environmentRepo.InstalledVersion("php", slug)}
|
||||
})
|
||||
|
||||
// Python 版本
|
||||
pythonData := lo.Map(s.environmentRepo.InstalledSlugs("python"), func(slug string, _ int) types.LV {
|
||||
return types.LV{Value: slug, Label: fmt.Sprintf("Python %s", s.environmentRepo.InstalledVersion("python", slug))}
|
||||
return types.LV{Value: slug, Label: "Python " + s.environmentRepo.InstalledVersion("python", slug)}
|
||||
})
|
||||
|
||||
// .NET 版本
|
||||
dotnetData := lo.Map(s.environmentRepo.InstalledSlugs("dotnet"), func(slug string, _ int) types.LV {
|
||||
return types.LV{Value: slug, Label: fmt.Sprintf(".NET %s", s.environmentRepo.InstalledVersion("dotnet", slug))}
|
||||
return types.LV{Value: slug, Label: ".NET " + s.environmentRepo.InstalledVersion("dotnet", slug)}
|
||||
})
|
||||
|
||||
// 数据库
|
||||
|
||||
@@ -49,8 +49,8 @@ func (s *SettingService) Update(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
restart := false
|
||||
if restart, err = s.settingRepo.UpdatePanel(r.Context(), req); err != nil {
|
||||
restart, err := s.settingRepo.UpdatePanel(r.Context(), req)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -430,7 +431,7 @@ func (s *ToolboxBenchmarkService) diskTestTask() map[string]any {
|
||||
for _, blockSize := range blockSizes {
|
||||
blockSizeKB := blockSize / 1024
|
||||
result := s.diskIOTest(testFile, blockSize)
|
||||
results[fmt.Sprintf("%d", blockSizeKB)] = result
|
||||
results[strconv.FormatInt(blockSizeKB, 10)] = result
|
||||
}
|
||||
duration := time.Since(start)
|
||||
results["score"] = s.calculateScore(duration)
|
||||
|
||||
@@ -1111,13 +1111,14 @@ func (s *ToolboxDiskService) parseAdaptec(output string) ([]raidController, []ra
|
||||
}
|
||||
|
||||
if inLogicalDev && currentArray != nil {
|
||||
if strings.HasPrefix(trimmed, "RAID level") {
|
||||
switch {
|
||||
case strings.HasPrefix(trimmed, "RAID level"):
|
||||
currentArray.RaidLevel = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Size") {
|
||||
case strings.HasPrefix(trimmed, "Size"):
|
||||
currentArray.Size = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Status of Logical Device") || strings.HasPrefix(trimmed, "Status of logical device") {
|
||||
case strings.HasPrefix(trimmed, "Status of Logical Device"), strings.HasPrefix(trimmed, "Status of logical device"):
|
||||
currentArray.State = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Stripe-size") || strings.HasPrefix(trimmed, "Strip Size") {
|
||||
case strings.HasPrefix(trimmed, "Stripe-size"), strings.HasPrefix(trimmed, "Strip Size"):
|
||||
currentArray.StripSize = s.extractAdaptecValue(trimmed)
|
||||
}
|
||||
}
|
||||
@@ -1132,15 +1133,16 @@ func (s *ToolboxDiskService) parseAdaptec(output string) ([]raidController, []ra
|
||||
}
|
||||
|
||||
if inPhysicalDev && currentDev != nil {
|
||||
if strings.HasPrefix(trimmed, "State") {
|
||||
switch {
|
||||
case strings.HasPrefix(trimmed, "State"):
|
||||
currentDev.State = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Size") {
|
||||
case strings.HasPrefix(trimmed, "Size"):
|
||||
currentDev.Size = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Model") {
|
||||
case strings.HasPrefix(trimmed, "Model"):
|
||||
currentDev.Model = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Serial number") || strings.HasPrefix(trimmed, "Serial Number") {
|
||||
case strings.HasPrefix(trimmed, "Serial number"), strings.HasPrefix(trimmed, "Serial Number"):
|
||||
currentDev.Serial = s.extractAdaptecValue(trimmed)
|
||||
} else if strings.HasPrefix(trimmed, "Reported Channel,Device") {
|
||||
case strings.HasPrefix(trimmed, "Reported Channel,Device"):
|
||||
currentDev.Slot = s.extractAdaptecValue(trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package service
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -410,23 +409,23 @@ func (s *WebsiteStatService) UpdateSetting(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.setting.Set(biz.SettingKeyWebsiteStatDays, fmt.Sprintf("%d", req.Days)); err != nil {
|
||||
if err = s.setting.Set(biz.SettingKeyWebsiteStatDays, strconv.FormatUint(uint64(req.Days), 10)); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if req.ErrBufMax > 0 {
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatErrBufMax, fmt.Sprintf("%d", req.ErrBufMax))
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatErrBufMax, strconv.Itoa(req.ErrBufMax))
|
||||
}
|
||||
if req.UVMaxKeys > 0 {
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatUVMaxKeys, fmt.Sprintf("%d", req.UVMaxKeys))
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatUVMaxKeys, strconv.Itoa(req.UVMaxKeys))
|
||||
}
|
||||
if req.IPMaxKeys > 0 {
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatIPMaxKeys, fmt.Sprintf("%d", req.IPMaxKeys))
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatIPMaxKeys, strconv.Itoa(req.IPMaxKeys))
|
||||
}
|
||||
if req.DetailMaxKeys > 0 {
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatDetailMaxKeys, fmt.Sprintf("%d", req.DetailMaxKeys))
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatDetailMaxKeys, strconv.Itoa(req.DetailMaxKeys))
|
||||
}
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatBodyEnabled, fmt.Sprintf("%t", req.BodyEnabled))
|
||||
_ = s.setting.Set(biz.SettingKeyWebsiteStatBodyEnabled, strconv.FormatBool(req.BodyEnabled))
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
@@ -594,7 +594,7 @@ func (s *WsService) getContainerSock() string {
|
||||
sock = "/var/run/docker.sock"
|
||||
}
|
||||
if !strings.Contains(sock, "://") {
|
||||
sock = fmt.Sprintf("unix://%s", sock)
|
||||
sock = "unix://" + sock
|
||||
}
|
||||
return sock
|
||||
}
|
||||
|
||||
+6
-6
@@ -39,8 +39,8 @@ const (
|
||||
|
||||
type EAB = acme.EAB
|
||||
|
||||
func NewRegisterAccount(ctx context.Context, email, CA string, eab *EAB, keyType KeyType, log *slog.Logger) (*Client, error) {
|
||||
client, err := getClient(CA, log)
|
||||
func NewRegisterAccount(ctx context.Context, email, ca string, eab *EAB, keyType KeyType, log *slog.Logger) (*Client, error) {
|
||||
client, err := getClient(ca, log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -69,8 +69,8 @@ func NewRegisterAccount(ctx context.Context, email, CA string, eab *EAB, keyType
|
||||
return &Client{Account: account, zClient: client}, nil
|
||||
}
|
||||
|
||||
func NewPrivateKeyAccount(email string, privateKey string, CA string, eab *EAB, log *slog.Logger) (*Client, error) {
|
||||
client, err := getClient(CA, log)
|
||||
func NewPrivateKeyAccount(email string, privateKey string, ca string, eab *EAB, log *slog.Logger) (*Client, error) {
|
||||
client, err := getClient(ca, log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -117,10 +117,10 @@ func generatePrivateKey(keyType KeyType) (crypto.Signer, error) {
|
||||
return nil, errors.New("unsupported key type")
|
||||
}
|
||||
|
||||
func getClient(CA string, log *slog.Logger) (acmez.Client, error) {
|
||||
func getClient(ca string, log *slog.Logger) (acmez.Client, error) {
|
||||
client := acmez.Client{
|
||||
Client: &acme.Client{
|
||||
Directory: CA,
|
||||
Directory: ca,
|
||||
HTTPClient: http.DefaultClient,
|
||||
Logger: log,
|
||||
},
|
||||
|
||||
+1
-1
@@ -434,7 +434,7 @@ func (s *dnsSolver) Present(ctx context.Context, challenge acme.Challenge) error
|
||||
return fmt.Errorf("failed to get DNS provider: %w", err)
|
||||
}
|
||||
|
||||
s.report(fmt.Sprintf("setting DNS TXT record %s", dnsName))
|
||||
s.report("setting DNS TXT record " + dnsName)
|
||||
|
||||
// 同时签主域 + 通配符(如 example.com 与 *.example.com)会产生两个 challenge,
|
||||
// 它们落在同一个 _acme-challenge.example.com TXT 名下,但 keyAuth 不同
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package api
|
||||
|
||||
import "fmt"
|
||||
|
||||
type EAB struct {
|
||||
KeyID string `json:"key_id"`
|
||||
MacKey string `json:"mac_key"`
|
||||
}
|
||||
|
||||
func (r *API) GoogleEAB() (*EAB, error) {
|
||||
resp, err := r.client.R().SetResult(&Response{}).Get("/acme/googleEAB")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !resp.IsStatusSuccess() {
|
||||
return nil, fmt.Errorf("failed to get google eab: %s", resp.String())
|
||||
}
|
||||
|
||||
eab, err := getResponseData[EAB](resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return eab, nil
|
||||
}
|
||||
+1
-1
@@ -48,7 +48,7 @@ func (r *API) Apps() (*Apps, error) {
|
||||
|
||||
// AppBySlug 根据slug返回应用
|
||||
func (r *API) AppBySlug(slug string) (*App, error) {
|
||||
resp, err := r.client.R().SetResult(&Response{}).Get(fmt.Sprintf("/apps/%s", slug))
|
||||
resp, err := r.client.R().SetResult(&Response{}).Get("/apps/" + slug)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ func (r *API) Templates() (*Templates, error) {
|
||||
|
||||
// TemplateBySlug 根据slug返回模版
|
||||
func (r *API) TemplateBySlug(slug string) (*Template, error) {
|
||||
resp, err := r.client.R().SetResult(&Response{}).Get(fmt.Sprintf("/templates/%s", slug))
|
||||
resp, err := r.client.R().SetResult(&Response{}).Get("/templates/" + slug)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ func GenerateSelfSigned(names []string) (cert []byte, key []byte, err error) {
|
||||
}
|
||||
}
|
||||
if len(dnsNames) == 0 && len(ipAddrs) == 0 {
|
||||
return nil, nil, fmt.Errorf("names is empty: SAN must not be empty")
|
||||
return nil, nil, errors.New("names is empty: SAN must not be empty")
|
||||
}
|
||||
|
||||
// 3) 随机 128 位序列号
|
||||
@@ -172,7 +172,7 @@ func GenerateSelfSignedRSA(hosts []string) (certPEM []byte, keyPEM []byte, err e
|
||||
}
|
||||
}
|
||||
if len(dnsNames) == 0 && len(ipAddrs) == 0 {
|
||||
return nil, nil, fmt.Errorf("hosts is empty: SAN must not be empty")
|
||||
return nil, nil, errors.New("hosts is empty: SAN must not be empty")
|
||||
}
|
||||
|
||||
// 3) 随机 128 位序列号
|
||||
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -20,7 +21,7 @@ type ClickHouse struct {
|
||||
// NewClickHouse 创建 ClickHouse 连接(HTTP API)
|
||||
func NewClickHouse(ctx context.Context, username, password, address string) (*ClickHouse, error) {
|
||||
client := resty.New()
|
||||
client.SetBaseURL(fmt.Sprintf("http://%s", address))
|
||||
client.SetBaseURL("http://" + address)
|
||||
client.SetTimeout(10 * 1000 * 1000 * 1000) // 10s
|
||||
|
||||
ch := &ClickHouse{
|
||||
@@ -66,7 +67,7 @@ func (r *ClickHouse) ping(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Query(query string, args ...any) (*sql.Rows, error) {
|
||||
return nil, fmt.Errorf("clickhouse HTTP API does not support sql.Rows")
|
||||
return nil, errors.New("clickhouse HTTP API does not support sql.Rows")
|
||||
}
|
||||
|
||||
func (r *ClickHouse) QueryRow(query string, args ...any) *sql.Row {
|
||||
@@ -79,7 +80,7 @@ func (r *ClickHouse) Exec(query string, args ...any) (sql.Result, error) {
|
||||
}
|
||||
|
||||
func (r *ClickHouse) Prepare(query string) (*sql.Stmt, error) {
|
||||
return nil, fmt.Errorf("clickhouse HTTP API does not support Prepare")
|
||||
return nil, errors.New("clickhouse HTTP API does not support Prepare")
|
||||
}
|
||||
|
||||
func (r *ClickHouse) DatabaseCreate(name string) error {
|
||||
|
||||
@@ -33,7 +33,7 @@ type ESDocument struct {
|
||||
// NewElasticsearch 创建 Elasticsearch 连接
|
||||
func NewElasticsearch(ctx context.Context, address, username, password string) (*Elasticsearch, error) {
|
||||
client := resty.New()
|
||||
client.SetBaseURL(fmt.Sprintf("http://%s", address))
|
||||
client.SetBaseURL("http://" + address)
|
||||
client.SetTimeout(10 * 1000 * 1000 * 1000) // 10s
|
||||
if username != "" && password != "" {
|
||||
client.SetBasicAuth(username, password)
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -125,7 +126,7 @@ func (r *Redis) Get(key string) (*RedisKV, error) {
|
||||
return nil, fmt.Errorf("key not found: %v", err)
|
||||
}
|
||||
if keyType == "none" {
|
||||
return nil, fmt.Errorf("key not found")
|
||||
return nil, errors.New("key not found")
|
||||
}
|
||||
|
||||
kv := &RedisKV{Key: key, Type: keyType}
|
||||
|
||||
@@ -225,7 +225,7 @@ func (r *firewalld) Port(rule FireInfo, operation Operation) error {
|
||||
func (r *firewalld) RichRules(rule FireInfo, operation Operation) error {
|
||||
// 出站规则下,必须指定具体的地址,否则会添加成入站规则
|
||||
if rule.Direction == "out" && rule.Address == "" {
|
||||
return fmt.Errorf("outbound rules must specify an address")
|
||||
return errors.New("outbound rules must specify an address")
|
||||
}
|
||||
|
||||
for _, protocol := range buildProtocols(rule.Protocol) {
|
||||
@@ -351,14 +351,15 @@ func (r *firewalld) parseRichRule(line string) (FireInfo, error) {
|
||||
}
|
||||
|
||||
ports := strings.Split(match[4], "-")
|
||||
if len(ports) == 2 { // 添加端口范围
|
||||
switch {
|
||||
case len(ports) == 2: // 添加端口范围
|
||||
fireInfo.PortStart = cast.ToUint(ports[0])
|
||||
fireInfo.PortEnd = cast.ToUint(ports[1])
|
||||
} else if len(ports) == 1 && ports[0] != "" { // 添加单个端口
|
||||
case len(ports) == 1 && ports[0] != "": // 添加单个端口
|
||||
port := cast.ToUint(ports[0])
|
||||
fireInfo.PortStart = port
|
||||
fireInfo.PortEnd = port
|
||||
} else if len(ports) == 1 && ports[0] == "" { // 未添加端口规则,表示所有端口
|
||||
case len(ports) == 1 && ports[0] == "": // 未添加端口规则,表示所有端口
|
||||
fireInfo.PortStart = 1
|
||||
fireInfo.PortEnd = 65535
|
||||
}
|
||||
|
||||
+5
-4
@@ -2,10 +2,12 @@ package firewall
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
@@ -123,8 +125,7 @@ func (r *ufw) parseRule(target, action, direction, source string) *FireInfo {
|
||||
// target 的 /tcp 是端口协议规格(如 80/tcp),不能剥离
|
||||
source = strings.TrimSpace(source)
|
||||
target = strings.TrimSpace(target)
|
||||
sourceProto := ""
|
||||
source, sourceProto = stripProtocolSuffix(source)
|
||||
source, sourceProto := stripProtocolSuffix(source)
|
||||
|
||||
// target 仅在 "Anywhere/tcp" 形式下才需要剥离协议后缀
|
||||
targetProto := ""
|
||||
@@ -273,7 +274,7 @@ func (r *ufw) deletePort(rule FireInfo) error {
|
||||
// formatPort 格式化端口(单端口或范围)
|
||||
func (r *ufw) formatPort(rule FireInfo) string {
|
||||
if rule.PortStart == rule.PortEnd {
|
||||
return fmt.Sprintf("%d", rule.PortStart)
|
||||
return strconv.FormatUint(uint64(rule.PortStart), 10)
|
||||
}
|
||||
return fmt.Sprintf("%d:%d", rule.PortStart, rule.PortEnd)
|
||||
}
|
||||
@@ -312,7 +313,7 @@ func (r *ufw) buildPortCmd(rule FireInfo, protocol string, operation Operation)
|
||||
func (r *ufw) RichRules(rule FireInfo, operation Operation) error {
|
||||
// 出站规则下,必须指定具体的地址
|
||||
if rule.Direction == "out" && rule.Address == "" {
|
||||
return fmt.Errorf("outbound rules must specify an address")
|
||||
return errors.New("outbound rules must specify an address")
|
||||
}
|
||||
|
||||
if rule.Protocol == "" {
|
||||
|
||||
+7
-5
@@ -2,6 +2,7 @@ package ntp
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"slices"
|
||||
@@ -99,7 +100,7 @@ func SetSystemNTPServers(servers []string) error {
|
||||
case NTPServiceChrony:
|
||||
return setChronyServers(servers)
|
||||
default:
|
||||
return fmt.Errorf("unsupported NTP service type")
|
||||
return errors.New("unsupported NTP service type")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,13 +156,14 @@ func setTimesyncdServers(servers []string) error {
|
||||
hasTimeSection := strings.Contains(content, "[Time]")
|
||||
ntpRegex := regexp.MustCompile(`(?m)^\s*#?\s*NTP\s*=.*$`)
|
||||
|
||||
if ntpRegex.MatchString(content) {
|
||||
switch {
|
||||
case ntpRegex.MatchString(content):
|
||||
// 替换现有的 NTP= 行
|
||||
content = ntpRegex.ReplaceAllString(content, ntpLine)
|
||||
} else if hasTimeSection {
|
||||
case hasTimeSection:
|
||||
// 在 [Time] 段后添加 NTP= 行
|
||||
content = strings.Replace(content, "[Time]", "[Time]\n"+ntpLine, 1)
|
||||
} else {
|
||||
default:
|
||||
// 添加 [Time] 段和 NTP= 行
|
||||
if content != "" && !strings.HasSuffix(content, "\n") {
|
||||
content += "\n"
|
||||
@@ -294,6 +296,6 @@ func RestartNTPService() error {
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported NTP service type")
|
||||
return errors.New("unsupported NTP service type")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package passkey
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -60,7 +61,7 @@ func (u *User) WebAuthnCredentials() []webauthn.Credential {
|
||||
// ParseUserID 从 WebAuthnID 字节还原 user ID
|
||||
func ParseUserID(userHandle []byte) (uint, error) {
|
||||
if len(userHandle) != 8 {
|
||||
return 0, fmt.Errorf("invalid user handle")
|
||||
return 0, errors.New("invalid user handle")
|
||||
}
|
||||
return uint(binary.BigEndian.Uint64(userHandle)), nil
|
||||
}
|
||||
|
||||
@@ -24,27 +24,6 @@ type ClientConfig struct {
|
||||
Timeout time.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
func ClientConfigPassword(host, user, password string) *ClientConfig {
|
||||
return &ClientConfig{
|
||||
Timeout: 10 * time.Second,
|
||||
AuthMethod: PASSWORD,
|
||||
Host: host,
|
||||
User: user,
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
|
||||
func ClientConfigPublicKey(host, user, key, passphrase string) *ClientConfig {
|
||||
return &ClientConfig{
|
||||
Timeout: 10 * time.Second,
|
||||
AuthMethod: PUBLICKEY,
|
||||
Host: host,
|
||||
User: user,
|
||||
Key: key,
|
||||
Passphrase: passphrase,
|
||||
}
|
||||
}
|
||||
|
||||
func NewSSHClient(conf ClientConfig) (*ssh.Client, error) {
|
||||
if conf.Timeout == 0 {
|
||||
conf.Timeout = 10 * time.Second
|
||||
|
||||
@@ -199,5 +199,5 @@ func (e *apiError) Error() string {
|
||||
if trimmed := bytes.TrimSpace(e.body); len(trimmed) > 0 {
|
||||
return fmt.Sprintf("s3: unexpected status %s: %s", e.statusText, trimmed)
|
||||
}
|
||||
return fmt.Sprintf("s3: unexpected status %s", e.statusText)
|
||||
return "s3: unexpected status " + e.statusText
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -37,7 +38,7 @@ func NewSFTP(config SFTPConfig) (Storage, error) {
|
||||
config.BasePath = strings.TrimSuffix(config.BasePath, "/")
|
||||
|
||||
if config.Username == "" || (config.Password == "" && config.PrivateKey == "") {
|
||||
return nil, fmt.Errorf("username and either password or private key must be provided")
|
||||
return nil, errors.New("username and either password or private key must be provided")
|
||||
}
|
||||
|
||||
return &SFTP{config: config}, nil
|
||||
|
||||
@@ -248,7 +248,7 @@ func generateRedirectConfig(redirect types.Redirect) string {
|
||||
cfg.Append(Dir("RewriteRule", "^(.*)$", to, fmt.Sprintf("[R=%d,L]", statusCode)))
|
||||
|
||||
case types.RedirectType404:
|
||||
cfg.Append(Cmt(fmt.Sprintf("404 redirect -> %s", redirect.To)))
|
||||
cfg.Append(Cmt("404 redirect -> " + redirect.To))
|
||||
cfg.Append(Dir("ErrorDocument", "404", redirect.To))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package apache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -37,7 +38,7 @@ type baseVhost struct {
|
||||
// newBaseVhost 创建基础虚拟主机实例
|
||||
func newBaseVhost(configDir string) (*baseVhost, error) {
|
||||
if configDir == "" {
|
||||
return nil, fmt.Errorf("config directory is required")
|
||||
return nil, errors.New("config directory is required")
|
||||
}
|
||||
|
||||
v := &baseVhost{
|
||||
@@ -76,7 +77,7 @@ func newBaseVhost(configDir string) (*baseVhost, error) {
|
||||
|
||||
// defaultConf 返回替换好站点名的默认配置模板
|
||||
func (v *baseVhost) defaultConf() string {
|
||||
return strings.ReplaceAll(DefaultVhostConf, "/opt/ace/sites/default", fmt.Sprintf("/opt/ace/sites/%s", v.siteName))
|
||||
return strings.ReplaceAll(DefaultVhostConf, "/opt/ace/sites/default", "/opt/ace/sites/"+v.siteName)
|
||||
}
|
||||
|
||||
// NewStaticVhost 创建纯静态虚拟主机实例
|
||||
@@ -359,7 +360,7 @@ func (v *baseVhost) SSLConfig() *types.SSLConfig {
|
||||
|
||||
func (v *baseVhost) SetSSLConfig(cfg *types.SSLConfig) error {
|
||||
if cfg == nil {
|
||||
return fmt.Errorf("SSL config cannot be nil")
|
||||
return errors.New("SSL config cannot be nil")
|
||||
}
|
||||
|
||||
v.vhost.Set("SSLEngine", "on")
|
||||
|
||||
@@ -20,7 +20,7 @@ type Parser struct {
|
||||
|
||||
// NewParser 使用网站名创建解析器,将默认配置中的 default 替换为实际网站名
|
||||
func NewParser(siteName string) (*Parser, error) {
|
||||
str := strings.ReplaceAll(DefaultConf, "/opt/ace/sites/default", fmt.Sprintf("/opt/ace/sites/%s", siteName))
|
||||
str := strings.ReplaceAll(DefaultConf, "/opt/ace/sites/default", "/opt/ace/sites/"+siteName)
|
||||
|
||||
p := parser.NewStringParser(str, parser.WithSkipIncludeParsingErr(), parser.WithSkipValidDirectivesErr())
|
||||
cfg, err := p.Parse()
|
||||
|
||||
@@ -93,7 +93,7 @@ func formatBytesToNginx(bytes int64) string {
|
||||
if bytes%1024 == 0 {
|
||||
return fmt.Sprintf("%dk", bytes/1024)
|
||||
}
|
||||
return fmt.Sprintf("%d", bytes)
|
||||
return strconv.FormatInt(bytes, 10)
|
||||
}
|
||||
|
||||
// formatDurationToNginx 格式化 time.Duration 为 Nginx 时间格式
|
||||
|
||||
@@ -2,10 +2,12 @@ package nginx
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
@@ -39,7 +41,7 @@ type baseVhost struct {
|
||||
// newBaseVhost 创建基础虚拟主机实例
|
||||
func newBaseVhost(configDir string) (*baseVhost, error) {
|
||||
if configDir == "" {
|
||||
return nil, fmt.Errorf("config directory is required")
|
||||
return nil, errors.New("config directory is required")
|
||||
}
|
||||
|
||||
v := &baseVhost{
|
||||
@@ -485,7 +487,7 @@ func (v *baseVhost) SSLConfig() *types.SSLConfig {
|
||||
|
||||
func (v *baseVhost) SetSSLConfig(cfg *types.SSLConfig) error {
|
||||
if cfg == nil {
|
||||
return fmt.Errorf("SSL config cannot be nil")
|
||||
return errors.New("SSL config cannot be nil")
|
||||
}
|
||||
|
||||
if err := v.ClearSSL(); err != nil {
|
||||
@@ -628,13 +630,13 @@ func (v *baseVhost) SetRateLimit(limit *types.RateLimit) error {
|
||||
if limit.PerServer > 0 {
|
||||
directives = append(directives, &config.Directive{
|
||||
Name: "limit_conn",
|
||||
Parameters: []config.Parameter{{Value: "perserver"}, {Value: fmt.Sprintf("%d", limit.PerServer)}},
|
||||
Parameters: []config.Parameter{{Value: "perserver"}, {Value: strconv.Itoa(limit.PerServer)}},
|
||||
})
|
||||
}
|
||||
if limit.PerIP > 0 {
|
||||
directives = append(directives, &config.Directive{
|
||||
Name: "limit_conn",
|
||||
Parameters: []config.Parameter{{Value: "perip"}, {Value: fmt.Sprintf("%d", limit.PerIP)}},
|
||||
Parameters: []config.Parameter{{Value: "perip"}, {Value: strconv.Itoa(limit.PerIP)}},
|
||||
})
|
||||
}
|
||||
if len(directives) > 0 {
|
||||
|
||||
@@ -13,19 +13,18 @@ func ParseUA(rawUA string) (browser, os string) {
|
||||
// 浏览器:名称 + 主版本号
|
||||
bName := string(agent.Browser())
|
||||
bMajor := agent.BrowserVersionMajor()
|
||||
if bName == "" {
|
||||
switch {
|
||||
case bName == "":
|
||||
browser = "Other"
|
||||
} else if bMajor == "" {
|
||||
case bMajor == "":
|
||||
browser = bName
|
||||
} else {
|
||||
default:
|
||||
browser = bName + " " + bMajor
|
||||
}
|
||||
|
||||
// 操作系统
|
||||
osName := string(agent.OS())
|
||||
if osName == "" {
|
||||
os = "Other"
|
||||
} else {
|
||||
os = "Other"
|
||||
if osName := string(agent.OS()); osName != "" {
|
||||
os = osName
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import base from './eslint.config'
|
||||
|
||||
export default [
|
||||
...(base as any),
|
||||
{
|
||||
name: 'unused-check',
|
||||
files: ['**/*.{ts,mts,tsx,vue}'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': ['error', { args: 'none', varsIgnorePattern: '^_', caughtErrors: 'none' }],
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -47,7 +47,6 @@ const onSelectMore = (key: string) => {
|
||||
if (!action) return
|
||||
if (action.confirm) {
|
||||
// 通过命令式确认替代下拉里的内联弹窗
|
||||
const { useConfirm } = (window as any).__useConfirm || {}
|
||||
void invokeWithConfirm(action)
|
||||
} else {
|
||||
void action.onClick(props.row)
|
||||
|
||||
@@ -6,7 +6,7 @@ interface Props {
|
||||
fallbackDescription?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
withDefaults(defineProps<Props>(), {
|
||||
fallbackTitle: undefined,
|
||||
fallbackDescription: undefined,
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
tooltip?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
withDefaults(defineProps<Props>(), {
|
||||
loading: false,
|
||||
size: 'small',
|
||||
variant: 'icon',
|
||||
|
||||
@@ -159,7 +159,7 @@ const { data: categories } = useRequest(app.categories, {
|
||||
initialData: [],
|
||||
})
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) =>
|
||||
app.list(page, pageSize, selectedCategory.value || undefined, searchQuery.value || undefined),
|
||||
{
|
||||
|
||||
@@ -155,7 +155,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) =>
|
||||
environment.list(
|
||||
page,
|
||||
|
||||
@@ -27,7 +27,7 @@ const searchQuery = ref<string>('')
|
||||
const deployModalShow = ref(false)
|
||||
const selectedTemplate = ref<Template | null>(null)
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) =>
|
||||
template.list(
|
||||
page,
|
||||
|
||||
@@ -161,7 +161,7 @@ const getWebsiteList = async (page: number, limit: number) => {
|
||||
addJailModel.value.website_name = websites.value[0]?.value
|
||||
}
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => fail2ban.jails(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -91,7 +91,7 @@ const userColumns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => pureftpd.list(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -105,7 +105,7 @@ const processColumns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => rsync.modules(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -58,7 +58,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => s3fs.mounts(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -183,7 +183,7 @@ const processColumns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => supervisor.processes(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -110,7 +110,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => backup.list(type.value, page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -130,7 +130,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => storage.list(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -117,7 +117,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => cert.accounts(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -371,7 +371,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => cert.certs(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -113,7 +113,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => cert.dns(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -213,7 +213,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => container.composeList(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -262,7 +262,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => container.containerList(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -117,7 +117,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => container.imageList(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -133,7 +133,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => container.networkList(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -86,7 +86,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => container.volumeList(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -91,7 +91,7 @@ const columns: any = computed(() => {
|
||||
return cols
|
||||
})
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => database.list(page, pageSize, props.type),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -205,7 +205,7 @@ const docColumns: any = [
|
||||
]
|
||||
|
||||
// 文档分页
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) =>
|
||||
database.esData(selectedServer.value || 0, selectedIndex.value, page, pageSize, search.value),
|
||||
{
|
||||
|
||||
@@ -186,7 +186,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) =>
|
||||
database.redisData(selectedServer.value || 0, selectedDB.value, page, pageSize, search.value),
|
||||
{
|
||||
|
||||
@@ -252,7 +252,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => database.serverList(page, pageSize, props.type),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -169,7 +169,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => database.userList(page, pageSize, props.type),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -101,7 +101,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => firewall.forwards(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -143,7 +143,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => firewall.ipRules(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
@@ -283,7 +283,7 @@ const columns: any = [
|
||||
},
|
||||
]
|
||||
|
||||
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
|
||||
const { loading, data, page, total, pageSize, refresh } = usePagination(
|
||||
(page, pageSize) => firewall.rules(page, pageSize),
|
||||
{
|
||||
initialData: { total: 0, list: [] },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user