mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
feat: 移除工具箱和跑分应用
This commit is contained in:
@@ -3,7 +3,6 @@ package apps
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
|
||||
"github.com/tnb-labs/panel/internal/apps/benchmark"
|
||||
"github.com/tnb-labs/panel/internal/apps/codeserver"
|
||||
"github.com/tnb-labs/panel/internal/apps/docker"
|
||||
"github.com/tnb-labs/panel/internal/apps/fail2ban"
|
||||
@@ -27,11 +26,9 @@ import (
|
||||
"github.com/tnb-labs/panel/internal/apps/rsync"
|
||||
"github.com/tnb-labs/panel/internal/apps/s3fs"
|
||||
"github.com/tnb-labs/panel/internal/apps/supervisor"
|
||||
"github.com/tnb-labs/panel/internal/apps/toolbox"
|
||||
)
|
||||
|
||||
var ProviderSet = wire.NewSet(
|
||||
benchmark.NewApp,
|
||||
codeserver.NewApp,
|
||||
docker.NewApp,
|
||||
fail2ban.NewApp,
|
||||
@@ -55,5 +52,4 @@ var ProviderSet = wire.NewSet(
|
||||
rsync.NewApp,
|
||||
s3fs.NewApp,
|
||||
supervisor.NewApp,
|
||||
toolbox.NewApp,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"github.com/tnb-labs/panel/internal/apps/benchmark"
|
||||
"github.com/tnb-labs/panel/internal/apps/codeserver"
|
||||
"github.com/tnb-labs/panel/internal/apps/docker"
|
||||
"github.com/tnb-labs/panel/internal/apps/fail2ban"
|
||||
@@ -25,12 +24,10 @@ import (
|
||||
"github.com/tnb-labs/panel/internal/apps/rsync"
|
||||
"github.com/tnb-labs/panel/internal/apps/s3fs"
|
||||
"github.com/tnb-labs/panel/internal/apps/supervisor"
|
||||
"github.com/tnb-labs/panel/internal/apps/toolbox"
|
||||
"github.com/tnb-labs/panel/pkg/apploader"
|
||||
)
|
||||
|
||||
func NewLoader(
|
||||
benchmark *benchmark.App,
|
||||
codeserver *codeserver.App,
|
||||
docker *docker.App,
|
||||
fail2ban *fail2ban.App,
|
||||
@@ -54,9 +51,8 @@ func NewLoader(
|
||||
rsync *rsync.App,
|
||||
s3fs *s3fs.App,
|
||||
supervisor *supervisor.App,
|
||||
toolbox *toolbox.App,
|
||||
) *apploader.Loader {
|
||||
loader := new(apploader.Loader)
|
||||
loader.Add(benchmark, codeserver, docker, fail2ban, frp, gitea, memcached, minio, mysql, nginx, php74, php80, php81, php82, php83, php84, phpmyadmin, podman, postgresql, pureftpd, redis, rsync, s3fs, supervisor, toolbox)
|
||||
loader.Add(codeserver, docker, fail2ban, frp, gitea, memcached, minio, mysql, nginx, php74, php80, php81, php82, php83, php84, phpmyadmin, podman, postgresql, pureftpd, redis, rsync, s3fs, supervisor)
|
||||
return loader
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/go-chi/chi/v5"
|
||||
"net"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-rat/chix"
|
||||
"github.com/go-rat/sessions"
|
||||
"github.com/knadh/koanf/v2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package benchmark
|
||||
package request
|
||||
|
||||
type Test struct {
|
||||
type ToolboxBenchmarkTest struct {
|
||||
Name string `json:"name" validate:"required|in:image,machine,compile,encryption,compression,physics,json,memory,disk"`
|
||||
Multi bool `json:"multi"`
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
package toolbox
|
||||
package request
|
||||
|
||||
import "time"
|
||||
|
||||
type DNS struct {
|
||||
type ToolboxSystemDNS struct {
|
||||
DNS1 string `form:"dns1" json:"dns1" validate:"required"`
|
||||
DNS2 string `form:"dns2" json:"dns2" validate:"required"`
|
||||
}
|
||||
|
||||
type SWAP struct {
|
||||
type ToolboxSystemSWAP struct {
|
||||
Size int64 `form:"size" json:"size" validate:"min:0"`
|
||||
}
|
||||
|
||||
type Timezone struct {
|
||||
type ToolboxSystemTimezone struct {
|
||||
Timezone string `form:"timezone" json:"timezone" validate:"required"`
|
||||
}
|
||||
|
||||
type Time struct {
|
||||
type ToolboxSystemTime struct {
|
||||
Time time.Time `form:"time" json:"time" validate:"required"`
|
||||
}
|
||||
|
||||
type Hostname struct {
|
||||
type ToolboxSystemHostname struct {
|
||||
Hostname string `form:"hostname" json:"hostname" validate:"required|regex:^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$"`
|
||||
}
|
||||
|
||||
type Hosts struct {
|
||||
type ToolboxSystemHosts struct {
|
||||
Hosts string `form:"hosts" json:"hosts"`
|
||||
}
|
||||
|
||||
type Password struct {
|
||||
type ToolboxSystemPassword struct {
|
||||
Password string `form:"password" json:"password" validate:"required|password"`
|
||||
}
|
||||
@@ -42,6 +42,8 @@ type Http struct {
|
||||
monitor *service.MonitorService
|
||||
setting *service.SettingService
|
||||
systemctl *service.SystemctlService
|
||||
toolboxSystem *service.ToolboxSystemService
|
||||
toolboxBenchmark *service.ToolboxBenchmarkService
|
||||
apps *apploader.Loader
|
||||
}
|
||||
|
||||
@@ -73,6 +75,8 @@ func NewHttp(
|
||||
monitor *service.MonitorService,
|
||||
setting *service.SettingService,
|
||||
systemctl *service.SystemctlService,
|
||||
toolboxSystem *service.ToolboxSystemService,
|
||||
toolboxBenchmark *service.ToolboxBenchmarkService,
|
||||
apps *apploader.Loader,
|
||||
) *Http {
|
||||
return &Http{
|
||||
@@ -103,6 +107,8 @@ func NewHttp(
|
||||
monitor: monitor,
|
||||
setting: setting,
|
||||
systemctl: systemctl,
|
||||
toolboxSystem: toolboxSystem,
|
||||
toolboxBenchmark: toolboxBenchmark,
|
||||
apps: apps,
|
||||
}
|
||||
}
|
||||
@@ -381,6 +387,26 @@ func (route *Http) Register(r *chi.Mux) {
|
||||
r.Post("/stop", route.systemctl.Stop)
|
||||
})
|
||||
|
||||
r.Route("/toolbox_system", func(r chi.Router) {
|
||||
r.Get("/dns", route.toolboxSystem.GetDNS)
|
||||
r.Post("/dns", route.toolboxSystem.UpdateDNS)
|
||||
r.Get("/swap", route.toolboxSystem.GetSWAP)
|
||||
r.Post("/swap", route.toolboxSystem.UpdateSWAP)
|
||||
r.Get("/timezone", route.toolboxSystem.GetTimezone)
|
||||
r.Post("/timezone", route.toolboxSystem.UpdateTimezone)
|
||||
r.Post("/time", route.toolboxSystem.UpdateTime)
|
||||
r.Post("/sync_time", route.toolboxSystem.SyncTime)
|
||||
r.Get("/hostname", route.toolboxSystem.GetHostname)
|
||||
r.Post("/hostname", route.toolboxSystem.UpdateHostname)
|
||||
r.Get("/hosts", route.toolboxSystem.GetHosts)
|
||||
r.Post("/hosts", route.toolboxSystem.UpdateHosts)
|
||||
r.Post("/root_password", route.toolboxSystem.UpdateRootPassword)
|
||||
})
|
||||
|
||||
r.Route("/toolbox_benchmark", func(r chi.Router) {
|
||||
r.Post("/test", route.toolboxBenchmark.Test)
|
||||
})
|
||||
|
||||
r.Route("/apps", func(r chi.Router) {
|
||||
route.apps.Register(r)
|
||||
})
|
||||
|
||||
@@ -32,5 +32,7 @@ var ProviderSet = wire.NewSet(
|
||||
NewUserService,
|
||||
NewUserTokenService,
|
||||
NewWebsiteService,
|
||||
NewToolboxSystemService,
|
||||
NewToolboxBenchmarkService,
|
||||
NewWsService,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package benchmark
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -21,69 +21,64 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
|
||||
"github.com/tnb-labs/panel/internal/service"
|
||||
"github.com/tnb-labs/panel/internal/http/request"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
type ToolboxBenchmarkService struct {
|
||||
t *gotext.Locale
|
||||
}
|
||||
|
||||
func NewApp(t *gotext.Locale) *App {
|
||||
return &App{
|
||||
func NewToolboxBenchmarkService(t *gotext.Locale) *ToolboxBenchmarkService {
|
||||
return &ToolboxBenchmarkService{
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *App) Route(r chi.Router) {
|
||||
r.Post("/test", s.Test)
|
||||
}
|
||||
|
||||
// Test 运行测试
|
||||
func (s *App) Test(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Test](r)
|
||||
func (s *ToolboxBenchmarkService) Test(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxBenchmarkTest](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
switch req.Name {
|
||||
case "image":
|
||||
result := s.imageProcessing(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "machine":
|
||||
result := s.machineLearning(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "compile":
|
||||
result := s.compileSimulationSingle(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "encryption":
|
||||
result := s.encryptionTest(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "compression":
|
||||
result := s.compressionTest(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "physics":
|
||||
result := s.physicsSimulation(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "json":
|
||||
result := s.jsonProcessing(req.Multi)
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "disk":
|
||||
result := s.diskTestTask()
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
case "memory":
|
||||
result := s.memoryTestTask()
|
||||
service.Success(w, result)
|
||||
Success(w, result)
|
||||
default:
|
||||
service.Error(w, http.StatusUnprocessableEntity, s.t.Get("unknown test type"))
|
||||
Error(w, http.StatusUnprocessableEntity, s.t.Get("unknown test type"))
|
||||
}
|
||||
}
|
||||
|
||||
// calculateCpuScore 计算CPU成绩
|
||||
func (s *App) calculateCpuScore(duration time.Duration) int {
|
||||
func (s *ToolboxBenchmarkService) calculateCpuScore(duration time.Duration) int {
|
||||
score := int((10 / duration.Seconds()) * float64(3000))
|
||||
|
||||
if score < 0 {
|
||||
@@ -93,7 +88,7 @@ func (s *App) calculateCpuScore(duration time.Duration) int {
|
||||
}
|
||||
|
||||
// calculateScore 计算内存/硬盘成绩
|
||||
func (s *App) calculateScore(duration time.Duration) int {
|
||||
func (s *ToolboxBenchmarkService) calculateScore(duration time.Duration) int {
|
||||
score := int((20 / duration.Seconds()) * float64(30000))
|
||||
|
||||
if score < 0 {
|
||||
@@ -104,7 +99,7 @@ func (s *App) calculateScore(duration time.Duration) int {
|
||||
|
||||
// 图像处理
|
||||
|
||||
func (s *App) imageProcessing(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) imageProcessing(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -117,7 +112,7 @@ func (s *App) imageProcessing(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) imageProcessingTask(numThreads int) error {
|
||||
func (s *ToolboxBenchmarkService) imageProcessingTask(numThreads int) error {
|
||||
img := image.NewRGBA(image.Rect(0, 0, 4000, 4000))
|
||||
for x := 0; x < 4000; x++ {
|
||||
for y := 0; y < 4000; y++ {
|
||||
@@ -166,7 +161,7 @@ func (s *App) imageProcessingTask(numThreads int) error {
|
||||
|
||||
// 机器学习(矩阵乘法)
|
||||
|
||||
func (s *App) machineLearning(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) machineLearning(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -177,7 +172,7 @@ func (s *App) machineLearning(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) machineLearningTask(numThreads int) {
|
||||
func (s *ToolboxBenchmarkService) machineLearningTask(numThreads int) {
|
||||
size := 900
|
||||
a := make([][]float64, size)
|
||||
b := make([][]float64, size)
|
||||
@@ -224,7 +219,7 @@ func (s *App) machineLearningTask(numThreads int) {
|
||||
|
||||
// 数学问题(计算斐波那契数)
|
||||
|
||||
func (s *App) compileSimulationSingle(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) compileSimulationSingle(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -258,7 +253,7 @@ func (s *App) compileSimulationSingle(multi bool) int {
|
||||
}
|
||||
|
||||
// 斐波那契函数
|
||||
func (s *App) fib(n int) *big.Int {
|
||||
func (s *ToolboxBenchmarkService) fib(n int) *big.Int {
|
||||
if n < 2 {
|
||||
return big.NewInt(int64(n))
|
||||
}
|
||||
@@ -275,7 +270,7 @@ func (s *App) fib(n int) *big.Int {
|
||||
|
||||
// AES加密
|
||||
|
||||
func (s *App) encryptionTest(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) encryptionTest(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -288,7 +283,7 @@ func (s *App) encryptionTest(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) encryptionTestTask(numThreads int) error {
|
||||
func (s *ToolboxBenchmarkService) encryptionTestTask(numThreads int) error {
|
||||
key := []byte("abcdefghijklmnopqrstuvwxyz123456")
|
||||
dataSize := 1024 * 1024 * 512 // 512 MB
|
||||
plaintext := []byte(strings.Repeat("A", dataSize))
|
||||
@@ -330,7 +325,7 @@ func (s *App) encryptionTestTask(numThreads int) error {
|
||||
|
||||
// 压缩/解压缩
|
||||
|
||||
func (s *App) compressionTest(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) compressionTest(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -341,7 +336,7 @@ func (s *App) compressionTest(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) compressionTestTask(numThreads int) {
|
||||
func (s *ToolboxBenchmarkService) compressionTestTask(numThreads int) {
|
||||
data := []byte(strings.Repeat("耗子面板", 50000000))
|
||||
chunkSize := len(data) / numThreads
|
||||
|
||||
@@ -391,7 +386,7 @@ func (s *App) compressionTestTask(numThreads int) {
|
||||
|
||||
// 物理仿真(N体问题)
|
||||
|
||||
func (s *App) physicsSimulation(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) physicsSimulation(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -402,7 +397,7 @@ func (s *App) physicsSimulation(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) physicsSimulationTask(numThreads int) {
|
||||
func (s *ToolboxBenchmarkService) physicsSimulationTask(numThreads int) {
|
||||
const (
|
||||
numBodies = 4000
|
||||
steps = 30
|
||||
@@ -489,7 +484,7 @@ func (s *App) physicsSimulationTask(numThreads int) {
|
||||
|
||||
// JSON解析
|
||||
|
||||
func (s *App) jsonProcessing(multi bool) int {
|
||||
func (s *ToolboxBenchmarkService) jsonProcessing(multi bool) int {
|
||||
n := 1
|
||||
if multi {
|
||||
n = runtime.NumCPU()
|
||||
@@ -500,7 +495,7 @@ func (s *App) jsonProcessing(multi bool) int {
|
||||
return s.calculateCpuScore(duration)
|
||||
}
|
||||
|
||||
func (s *App) jsonProcessingTask(numThreads int) {
|
||||
func (s *ToolboxBenchmarkService) jsonProcessingTask(numThreads int) {
|
||||
numElements := 1000000
|
||||
elementsPerThread := numElements / numThreads
|
||||
|
||||
@@ -541,7 +536,7 @@ func (s *App) jsonProcessingTask(numThreads int) {
|
||||
|
||||
// 内存性能
|
||||
|
||||
func (s *App) memoryTestTask() map[string]any {
|
||||
func (s *ToolboxBenchmarkService) memoryTestTask() map[string]any {
|
||||
results := make(map[string]any)
|
||||
dataSize := 500 * 1024 * 1024 // 500 MB
|
||||
data := make([]byte, dataSize)
|
||||
@@ -559,7 +554,7 @@ func (s *App) memoryTestTask() map[string]any {
|
||||
return results
|
||||
}
|
||||
|
||||
func (s *App) memoryBandwidthTest(data []byte) string {
|
||||
func (s *ToolboxBenchmarkService) memoryBandwidthTest(data []byte) string {
|
||||
dataSize := len(data)
|
||||
|
||||
startTime := time.Now()
|
||||
@@ -576,7 +571,7 @@ func (s *App) memoryBandwidthTest(data []byte) string {
|
||||
return fmt.Sprintf("%.2f MB/s", speed)
|
||||
}
|
||||
|
||||
func (s *App) memoryLatencyTest(data []byte) string {
|
||||
func (s *ToolboxBenchmarkService) memoryLatencyTest(data []byte) string {
|
||||
dataSize := len(data)
|
||||
indices := rand.Perm(dataSize)
|
||||
|
||||
@@ -595,7 +590,7 @@ func (s *App) memoryLatencyTest(data []byte) string {
|
||||
|
||||
// 硬盘IO
|
||||
|
||||
func (s *App) diskTestTask() map[string]any {
|
||||
func (s *ToolboxBenchmarkService) diskTestTask() map[string]any {
|
||||
results := make(map[string]any)
|
||||
blockSizes := []int64{4 * 1024, 64 * 1024, 512 * 1024, 1 * 1024 * 1024} // 4K, 64K, 512K, 1M
|
||||
fileSize := int64(100 * 1024 * 1024) // 100MB 文件
|
||||
@@ -611,7 +606,7 @@ func (s *App) diskTestTask() map[string]any {
|
||||
return results
|
||||
}
|
||||
|
||||
func (s *App) diskIOTest(blockSize int64, fileSize int64) map[string]any {
|
||||
func (s *ToolboxBenchmarkService) diskIOTest(blockSize int64, fileSize int64) map[string]any {
|
||||
result := make(map[string]any)
|
||||
tempFile := fmt.Sprintf("tempfile_%d", blockSize)
|
||||
defer func(name string) {
|
||||
@@ -631,7 +626,7 @@ func (s *App) diskIOTest(blockSize int64, fileSize int64) map[string]any {
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *App) diskWriteTest(fileName string, blockSize int64, fileSize int64) (float64, float64) {
|
||||
func (s *ToolboxBenchmarkService) diskWriteTest(fileName string, blockSize int64, fileSize int64) (float64, float64) {
|
||||
totalBlocks := fileSize / blockSize
|
||||
|
||||
data := make([]byte, blockSize)
|
||||
@@ -667,7 +662,7 @@ func (s *App) diskWriteTest(fileName string, blockSize int64, fileSize int64) (f
|
||||
return speed, iops
|
||||
}
|
||||
|
||||
func (s *App) diskReadTest(fileName string, blockSize int64, fileSize int64) (float64, float64) {
|
||||
func (s *ToolboxBenchmarkService) diskReadTest(fileName string, blockSize int64, fileSize int64) (float64, float64) {
|
||||
totalBlocks := fileSize / blockSize
|
||||
|
||||
data := make([]byte, blockSize)
|
||||
@@ -1,4 +1,4 @@
|
||||
package toolbox
|
||||
package service
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@@ -7,13 +7,12 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-rat/chix"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/tnb-labs/panel/internal/app"
|
||||
"github.com/tnb-labs/panel/internal/service"
|
||||
"github.com/tnb-labs/panel/internal/http/request"
|
||||
"github.com/tnb-labs/panel/pkg/io"
|
||||
"github.com/tnb-labs/panel/pkg/ntp"
|
||||
"github.com/tnb-labs/panel/pkg/shell"
|
||||
@@ -21,37 +20,21 @@ import (
|
||||
"github.com/tnb-labs/panel/pkg/types"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
type ToolboxSystemService struct {
|
||||
t *gotext.Locale
|
||||
}
|
||||
|
||||
func NewApp(t *gotext.Locale) *App {
|
||||
return &App{
|
||||
func NewToolboxSystemService(t *gotext.Locale) *ToolboxSystemService {
|
||||
return &ToolboxSystemService{
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *App) Route(r chi.Router) {
|
||||
r.Get("/dns", s.GetDNS)
|
||||
r.Post("/dns", s.UpdateDNS)
|
||||
r.Get("/swap", s.GetSWAP)
|
||||
r.Post("/swap", s.UpdateSWAP)
|
||||
r.Get("/timezone", s.GetTimezone)
|
||||
r.Post("/timezone", s.UpdateTimezone)
|
||||
r.Post("/time", s.UpdateTime)
|
||||
r.Post("/sync_time", s.SyncTime)
|
||||
r.Get("/hostname", s.GetHostname)
|
||||
r.Post("/hostname", s.UpdateHostname)
|
||||
r.Get("/hosts", s.GetHosts)
|
||||
r.Post("/hosts", s.UpdateHosts)
|
||||
r.Post("/root_password", s.UpdateRootPassword)
|
||||
}
|
||||
|
||||
// GetDNS 获取 DNS 信息
|
||||
func (s *App) GetDNS(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) GetDNS(w http.ResponseWriter, r *http.Request) {
|
||||
raw, err := io.Read("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -61,14 +44,14 @@ func (s *App) GetDNS(w http.ResponseWriter, r *http.Request) {
|
||||
dns = append(dns, m[1])
|
||||
}
|
||||
|
||||
service.Success(w, dns)
|
||||
Success(w, dns)
|
||||
}
|
||||
|
||||
// UpdateDNS 设置 DNS 信息
|
||||
func (s *App) UpdateDNS(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[DNS](r)
|
||||
func (s *ToolboxSystemService) UpdateDNS(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemDNS](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -77,21 +60,21 @@ func (s *App) UpdateDNS(w http.ResponseWriter, r *http.Request) {
|
||||
dns += "nameserver " + req.DNS2 + "\n"
|
||||
|
||||
if err := io.Write("/etc/resolv.conf", dns, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to update DNS: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to update DNS: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// GetSWAP 获取 SWAP 信息
|
||||
func (s *App) GetSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) GetSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
var total, used, free string
|
||||
var size int64
|
||||
if io.Exists(filepath.Join(app.Root, "swap")) {
|
||||
file, err := os.Stat(filepath.Join(app.Root, "swap"))
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get SWAP: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to get SWAP: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -104,7 +87,7 @@ func (s *App) GetSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
raw, err := shell.Execf("free | grep Swap")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get SWAP: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to get SWAP: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,7 +97,7 @@ func (s *App) GetSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
free = tools.FormatBytes(cast.ToFloat64(match[3]) * 1024)
|
||||
}
|
||||
|
||||
service.Success(w, chix.M{
|
||||
Success(w, chix.M{
|
||||
"total": total,
|
||||
"size": size,
|
||||
"used": used,
|
||||
@@ -123,24 +106,24 @@ func (s *App) GetSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// UpdateSWAP 设置 SWAP 信息
|
||||
func (s *App) UpdateSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[SWAP](r)
|
||||
func (s *ToolboxSystemService) UpdateSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemSWAP](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if io.Exists(filepath.Join(app.Root, "swap")) {
|
||||
if _, err = shell.Execf("swapoff '%s'", filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if _, err = shell.Execf("rm -f '%s'", filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if _, err = shell.Execf(`sed -i "\|^%s|d" /etc/fstab`, filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -149,52 +132,52 @@ func (s *App) UpdateSWAP(w http.ResponseWriter, r *http.Request) {
|
||||
var free string
|
||||
free, err = shell.Execf("df -k %s | awk '{print $4}' | tail -n 1", app.Root)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get disk space: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to get disk space: %v", err))
|
||||
return
|
||||
}
|
||||
if cast.ToInt64(free)*1024 < req.Size*1024*1024 {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("disk space is insufficient, current free %s", tools.FormatBytes(cast.ToFloat64(free))))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("disk space is insufficient, current free %s", tools.FormatBytes(cast.ToFloat64(free))))
|
||||
return
|
||||
}
|
||||
|
||||
btrfsCheck, _ := shell.Execf("df -T %s | awk '{print $2}' | tail -n 1", app.Root)
|
||||
if strings.Contains(btrfsCheck, "btrfs") {
|
||||
if _, err = shell.Execf("btrfs filesystem mkswapfile --size %dM --uuid clear %s", req.Size, filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if _, err = shell.Execf("dd if=/dev/zero of=%s bs=1M count=%d", filepath.Join(app.Root, "swap"), req.Size); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if _, err = shell.Execf("mkswap -f '%s'", filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if err = io.Chmod(filepath.Join(app.Root, "swap"), 0600); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set SWAP permission: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to set SWAP permission: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
if _, err = shell.Execf("swapon '%s'", filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if _, err = shell.Execf("echo '%s swap swap defaults 0 0' >> /etc/fstab", filepath.Join(app.Root, "swap")); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// GetTimezone 获取时区
|
||||
func (s *App) GetTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) GetTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
raw, err := shell.Execf("timedatectl | grep zone")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get timezone: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to get timezone: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -205,7 +188,7 @@ func (s *App) GetTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
zonesRaw, err := shell.Execf("timedatectl list-timezones")
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to get available timezones: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to get available timezones: %v", err))
|
||||
return
|
||||
}
|
||||
zones := strings.Split(zonesRaw, "\n")
|
||||
@@ -218,121 +201,121 @@ func (s *App) GetTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
service.Success(w, chix.M{
|
||||
Success(w, chix.M{
|
||||
"timezone": match[1],
|
||||
"timezones": zonesList,
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateTimezone 设置时区
|
||||
func (s *App) UpdateTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Timezone](r)
|
||||
func (s *ToolboxSystemService) UpdateTimezone(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemTimezone](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = shell.Execf("timedatectl set-timezone '%s'", req.Timezone); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// UpdateTime 设置时间
|
||||
func (s *App) UpdateTime(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Time](r)
|
||||
func (s *ToolboxSystemService) UpdateTime(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemTime](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = ntp.UpdateSystemTime(req.Time); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
|
||||
}
|
||||
|
||||
// SyncTime 同步时间
|
||||
func (s *App) SyncTime(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) SyncTime(w http.ResponseWriter, r *http.Request) {
|
||||
now, err := ntp.Now()
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = ntp.UpdateSystemTime(now); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", err)
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// GetHostname 获取主机名
|
||||
func (s *App) GetHostname(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) GetHostname(w http.ResponseWriter, r *http.Request) {
|
||||
hostname, _ := io.Read("/etc/hostname")
|
||||
service.Success(w, strings.TrimSpace(hostname))
|
||||
Success(w, strings.TrimSpace(hostname))
|
||||
}
|
||||
|
||||
// UpdateHostname 设置主机名
|
||||
func (s *App) UpdateHostname(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Hostname](r)
|
||||
func (s *ToolboxSystemService) UpdateHostname(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemHostname](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = shell.Execf("hostnamectl set-hostname '%s'", req.Hostname); err != nil {
|
||||
// 直接写 /etc/hostname
|
||||
if err = io.Write("/etc/hostname", req.Hostname, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set hostname: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to set hostname: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// GetHosts 获取 hosts 信息
|
||||
func (s *App) GetHosts(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *ToolboxSystemService) GetHosts(w http.ResponseWriter, r *http.Request) {
|
||||
hosts, _ := io.Read("/etc/hosts")
|
||||
service.Success(w, hosts)
|
||||
Success(w, hosts)
|
||||
}
|
||||
|
||||
// UpdateHosts 设置 hosts 信息
|
||||
func (s *App) UpdateHosts(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Hosts](r)
|
||||
func (s *ToolboxSystemService) UpdateHosts(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemHosts](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = io.Write("/etc/hosts", req.Hosts, 0644); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, s.t.Get("failed to set hosts: %v", err))
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to set hosts: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// UpdateRootPassword 设置 root 密码
|
||||
func (s *App) UpdateRootPassword(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := service.Bind[Password](r)
|
||||
func (s *ToolboxSystemService) UpdateRootPassword(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSystemPassword](r)
|
||||
if err != nil {
|
||||
service.Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
req.Password = strings.ReplaceAll(req.Password, `'`, `\'`)
|
||||
if _, err = shell.Execf(`yes '%s' | passwd root`, req.Password); err != nil {
|
||||
service.Error(w, http.StatusInternalServerError, "%v", s.t.Get("failed to set root password: %v", err))
|
||||
Error(w, http.StatusInternalServerError, "%v", s.t.Get("failed to set root password: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
service.Success(w, nil)
|
||||
Success(w, nil)
|
||||
}
|
||||
Reference in New Issue
Block a user