From aac8fe85bad5e3d907e85e6866bcdbad36c37f56 Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Fri, 9 Sep 2022 06:46:51 +0100 Subject: [PATCH 01/21] update the way environment variables are displayed --- route/v1/docker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/route/v1/docker.go b/route/v1/docker.go index 6eb534413..05ebddf46 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -38,7 +38,7 @@ var upgrader = websocket.Upgrader{ HandshakeTimeout: time.Duration(time.Second * 5), } -//打开docker的terminal +// 打开docker的terminal func DockerTerminal(c *gin.Context) { col := c.DefaultQuery("cols", "100") row := c.DefaultQuery("rows", "30") @@ -1126,7 +1126,7 @@ func ContainerUpdateInfo(c *gin.Context) { } } for _, v := range info.Config.Env { - if len(showENVList) > 0 { + if len(showENVList) > 0 && info.Config.Labels["origin"] != "local" { if _, ok := showENVMap[strings.Split(v, "=")[0]]; ok { temp := model.Env{ Name: strings.Split(v, "=")[0], From 4434ba522ba1665c99aa86c8ef2f612b061889e1 Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Fri, 9 Sep 2022 07:36:49 +0100 Subject: [PATCH 02/21] update upgrade script address --- build/sysroot/usr/share/casaos/shell/update.sh | 2 +- service/system.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/sysroot/usr/share/casaos/shell/update.sh b/build/sysroot/usr/share/casaos/shell/update.sh index fdae5ca0f..2b8765493 100644 --- a/build/sysroot/usr/share/casaos/shell/update.sh +++ b/build/sysroot/usr/share/casaos/shell/update.sh @@ -9,4 +9,4 @@ ### -curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/new.update.sh | bash \ No newline at end of file +curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/upgrade.sh | bash \ No newline at end of file diff --git a/service/system.go b/service/system.go index c6ed444bd..b332d01ed 100644 --- a/service/system.go +++ b/service/system.go @@ -221,7 +221,7 @@ func (s *systemService) UpdateSystemVersion(version string) { } file.CreateFile(config.AppInfo.LogPath + "/upgrade.log") //go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/update.sh | bash") - go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | sudo bash") + go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/upgrade.sh | bash") //s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) //s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)) } From fb39529e8fe953ac0ab66d482d78aae277fa1e0d Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Sat, 10 Sep 2022 01:00:01 +0100 Subject: [PATCH 03/21] update common package --- build/sysroot/usr/share/casaos/shell/update.sh | 2 +- go.mod | 2 +- go.sum | 2 ++ service/system.go | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build/sysroot/usr/share/casaos/shell/update.sh b/build/sysroot/usr/share/casaos/shell/update.sh index 2b8765493..380210524 100644 --- a/build/sysroot/usr/share/casaos/shell/update.sh +++ b/build/sysroot/usr/share/casaos/shell/update.sh @@ -9,4 +9,4 @@ ### -curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/upgrade.sh | bash \ No newline at end of file +curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash \ No newline at end of file diff --git a/go.mod b/go.mod index 6af729f88..6209c3e2d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d - github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9 + github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5 github.com/IceWhaleTech/CasaOS-Gateway v0.3.6 github.com/Microsoft/go-winio v0.5.0 // indirect github.com/ambelovsky/go-structs v1.1.0 // indirect diff --git a/go.sum b/go.sum index 45192e236..9707bb2ee 100644 --- a/go.sum +++ b/go.sum @@ -85,6 +85,8 @@ github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9 h1:q4I/lSsCooxdd6LxinGy90y0n6V8EcaPBV1JCfpEnV4= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5 h1:vgAf0jVKCBo3wyjOZ4z9tB77lVrgIfz2CcQX2+4JTSI= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= github.com/IceWhaleTech/CasaOS-Gateway v0.3.6 h1:2tQQo85+jzbbjqIsKKn77QlAA73bc7vZsVCFvWnK4mg= github.com/IceWhaleTech/CasaOS-Gateway v0.3.6/go.mod h1:hnZwGUzcOyiufMpVO7l3gu2gAm6Ws4TY4Nlj3kMshXA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= diff --git a/service/system.go b/service/system.go index b332d01ed..8717e4c94 100644 --- a/service/system.go +++ b/service/system.go @@ -221,7 +221,7 @@ func (s *systemService) UpdateSystemVersion(version string) { } file.CreateFile(config.AppInfo.LogPath + "/upgrade.log") //go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/LinkLeong/casaos-alpha/main/update.sh | bash") - go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/upgrade.sh | bash") + go command2.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash") //s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) //s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)) } From 466350dd212048585e7cee9627297b6b80629467 Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Tue, 13 Sep 2022 07:02:21 +0100 Subject: [PATCH 04/21] update CasaOS-Common --- go.sum | 1 - 1 file changed, 1 deletion(-) diff --git a/go.sum b/go.sum index 9707bb2ee..9e68d0ead 100644 --- a/go.sum +++ b/go.sum @@ -83,7 +83,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU= github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9 h1:q4I/lSsCooxdd6LxinGy90y0n6V8EcaPBV1JCfpEnV4= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5 h1:vgAf0jVKCBo3wyjOZ4z9tB77lVrgIfz2CcQX2+4JTSI= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= From d14381e6a2498c7a9bffa79c4e4927947e1237f7 Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Thu, 8 Sep 2022 10:55:20 +0100 Subject: [PATCH 05/21] add send notify function --- .../migration/service.d/casaos/migration.list | 1 + cmd/migration-tool/log.go | 10 --- cmd/migration-tool/main.go | 1 + cmd/migration-tool/migration-034-035.go | 10 +-- cmd/migration-tool/migration-036.go | 74 +++++++++++++++++++ common/notify.go | 67 +++++++++++++++++ main.go | 14 +++- route/route.go | 9 ++- route/v1/docker.go | 2 +- route/v1/notiry.go | 16 ++++ service/notify.go | 16 ++++ 11 files changed, 202 insertions(+), 18 deletions(-) create mode 100644 cmd/migration-tool/migration-036.go create mode 100644 common/notify.go create mode 100644 route/v1/notiry.go diff --git a/build/scripts/migration/service.d/casaos/migration.list b/build/scripts/migration/service.d/casaos/migration.list index 2035e4238..d3ce03f38 100644 --- a/build/scripts/migration/service.d/casaos/migration.list +++ b/build/scripts/migration/service.d/casaos/migration.list @@ -1,3 +1,4 @@ LEGACY_WITHOUT_VERSION v0.3.6 v0.3.5 v0.3.6 v0.3.5.1 v0.3.6 +v0.3.6 v0.3.7 diff --git a/cmd/migration-tool/log.go b/cmd/migration-tool/log.go index e20da6994..ed699830a 100644 --- a/cmd/migration-tool/log.go +++ b/cmd/migration-tool/log.go @@ -1,13 +1,3 @@ -/* - * @Author: LinkLeong link@icewhale.org - * @Date: 2022-08-30 22:15:30 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-08-30 22:15:47 - * @FilePath: /CasaOS/cmd/migration-tool/log.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ package main import ( diff --git a/cmd/migration-tool/main.go b/cmd/migration-tool/main.go index a09d5b8a4..5f7c60b59 100644 --- a/cmd/migration-tool/main.go +++ b/cmd/migration-tool/main.go @@ -80,6 +80,7 @@ func main() { migrationTools := []interfaces.MigrationTool{ NewMigrationToolFor_035(), + NewMigrationToolFor_036(), } var selectedMigrationTool interfaces.MigrationTool diff --git a/cmd/migration-tool/migration-034-035.go b/cmd/migration-tool/migration-034-035.go index 4fa2ed3c5..3dfed609a 100644 --- a/cmd/migration-tool/migration-034-035.go +++ b/cmd/migration-tool/migration-034-035.go @@ -25,9 +25,9 @@ import ( "github.com/IceWhaleTech/CasaOS/service" ) -type migrationTool struct{} +type migrationTool036 struct{} -func (u *migrationTool) IsMigrationNeeded() (bool, error) { +func (u *migrationTool036) IsMigrationNeeded() (bool, error) { majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion() if err != nil { @@ -55,12 +55,12 @@ func (u *migrationTool) IsMigrationNeeded() (bool, error) { } -func (u *migrationTool) PreMigrate() error { +func (u *migrationTool036) PreMigrate() error { return nil } -func (u *migrationTool) Migrate() error { +func (u *migrationTool036) Migrate() error { if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { service.MyService.System().UpdateUSBAutoMount("False") @@ -173,7 +173,7 @@ func (u *migrationTool) Migrate() error { return nil } -func (u *migrationTool) PostMigrate() error { +func (u *migrationTool036) PostMigrate() error { return nil } diff --git a/cmd/migration-tool/migration-036.go b/cmd/migration-tool/migration-036.go new file mode 100644 index 000000000..b6d54103c --- /dev/null +++ b/cmd/migration-tool/migration-036.go @@ -0,0 +1,74 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-08-24 17:36:00 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-09-05 11:24:27 + * @FilePath: /CasaOS/cmd/migration-tool/migration-034-035.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package main + +import ( + "strings" + + interfaces "github.com/IceWhaleTech/CasaOS-Common" + "github.com/IceWhaleTech/CasaOS-Common/utils/version" + "github.com/IceWhaleTech/CasaOS/pkg/config" + "github.com/IceWhaleTech/CasaOS/service" +) + +type migrationTool struct{} + +func (u *migrationTool) IsMigrationNeeded() (bool, error) { + + majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion() + if err != nil { + if err == version.ErrLegacyVersionNotFound { + return false, nil + } + + return false, err + } + + if majorVersion > 0 { + return false, nil + } + + if minorVersion > 3 { + return false, nil + } + + if minorVersion == 3 && patchVersion > 5 { + return false, nil + } + + _logger.Info("Migration is needed for a CasaOS version 0.3.5 and older...") + return true, nil + +} + +func (u *migrationTool) PreMigrate() error { + + return nil +} + +func (u *migrationTool) Migrate() error { + + if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { + service.MyService.System().UpdateUSBAutoMount("False") + service.MyService.System().ExecUSBAutoMountShell("False") + } + + _logger.Info("update done") + return nil +} + +func (u *migrationTool) PostMigrate() error { + return nil +} + +func NewMigrationToolFor_036() interfaces.MigrationTool { + return &migrationTool{} +} diff --git a/common/notify.go b/common/notify.go new file mode 100644 index 000000000..4a003d076 --- /dev/null +++ b/common/notify.go @@ -0,0 +1,67 @@ +package common + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "path/filepath" + "strings" +) + +const ( + CasaOSURLFilename = "casaos.url" + APICasaOSNotify = "/v1/notiry" +) + +type NotifyService interface { + SendNotify(path string, message map[string]interface{}) error +} +type notifyService struct { + address string +} + +func (n *notifyService) SendNotify(path string, message map[string]interface{}) error { + + url := strings.TrimSuffix(n.address, "/") + "/" + APICasaOSNotify + "/" + path + body, err := json.Marshal(message) + if err != nil { + return err + } + response, err := http.Post(url, "application/json", bytes.NewBuffer(body)) + if err != nil { + return err + } + + if response.StatusCode != http.StatusCreated { + return errors.New("failed to send notify (status code: " + fmt.Sprint(response.StatusCode) + ")") + } + return nil + +} + +func NewNotifyService(runtimePath string) (NotifyService, error) { + casaosAddressFile := filepath.Join(runtimePath, CasaOSURLFilename) + + buf, err := os.ReadFile(casaosAddressFile) + if err != nil { + return nil, err + } + + address := string(buf) + + response, err := http.Get(address + "/ping") + if err != nil { + return nil, err + } + + if response.StatusCode != 200 { + return nil, errors.New("failed to ping casaos service") + } + + return ¬ifyService{ + address: address, + }, nil +} diff --git a/main.go b/main.go index b616e52f1..6ff7af859 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "net/http" + "path/filepath" "time" "github.com/IceWhaleTech/CasaOS-Gateway/common" @@ -12,10 +13,12 @@ import ( "github.com/IceWhaleTech/CasaOS/pkg/cache" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/sqlite" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/IceWhaleTech/CasaOS/route" "github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/types" + "go.uber.org/zap" "github.com/robfig/cron" "gorm.io/gorm" @@ -107,7 +110,7 @@ func main() { if err != nil { panic(err) } - routers := []string{"sys", "apps", "container", "app-categories", "port", "file", "folder", "batch", "image", "disks", "storage", "samba"} + routers := []string{"sys", "apps", "container", "app-categories", "port", "file", "folder", "batch", "image", "disks", "storage", "samba", "notify"} for _, v := range routers { err = service.MyService.Gateway().CreateRoute(&common.Route{ Path: "/v1/" + v, @@ -141,6 +144,15 @@ func main() { // MaxHeaderBytes: 1 << 20, // } // s.ListenAndServe() + urlFilePath := filepath.Join(config.CommonInfo.RuntimePath, "casaos.url") + err = file.CreateFileAndWriteContent(urlFilePath, "http://"+listener.Addr().String()) + if err != nil { + loger.Error("Management service is listening...", + zap.Any("address", listener.Addr().String()), + zap.Any("filepath", urlFilePath), + ) + } + err = http.Serve(listener, r) if err != nil { panic(err) diff --git a/route/route.go b/route/route.go index 2ce2dc368..39d011b70 100644 --- a/route/route.go +++ b/route/route.go @@ -40,7 +40,9 @@ func InitRouter() *gin.Engine { r.GET("/v1/sys/socket-port", v1.GetSystemSocketPort) //sys/socket_port r.GET("/v1/sys/version/check", v1.GetSystemCheckVersion) - + r.GET("/ping", func(ctx *gin.Context) { + ctx.String(200, "pong") + }) v1Group := r.Group("/v1") v1Group.Use(jwt2.JWT()) @@ -238,6 +240,11 @@ func InitRouter() *gin.Engine { v1SharesGroup.GET("/status", v1.GetSambaStatus) } } + v1NotifyGroup := v1Group.Group("/notify") + v1NotifyGroup.Use() + { + v1NotifyGroup.POST("/:path", v1.PostNotifyMssage) + } } return r } diff --git a/route/v1/docker.go b/route/v1/docker.go index 05ebddf46..8c1254f42 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -877,7 +877,7 @@ func UpdateSetting(c *gin.Context) { if err != nil { service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id) service.MyService.Docker().DockerContainerStart(id) - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) return } // echo -e "hellow\nworld" >> diff --git a/route/v1/notiry.go b/route/v1/notiry.go new file mode 100644 index 000000000..c818aab0d --- /dev/null +++ b/route/v1/notiry.go @@ -0,0 +1,16 @@ +package v1 + +import ( + "github.com/IceWhaleTech/CasaOS/model" + "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" + "github.com/IceWhaleTech/CasaOS/service" + "github.com/gin-gonic/gin" +) + +func PostNotifyMssage(c *gin.Context) { + path := c.Param("path") + message := make(map[string]interface{}) + c.ShouldBind(&message) + service.MyService.Notify().SendNotify(path, message) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} diff --git a/service/notify.go b/service/notify.go index 3981e551f..154d45a4d 100644 --- a/service/notify.go +++ b/service/notify.go @@ -37,12 +37,28 @@ type NotifyServer interface { SendInstallAppBySocket(app notify.Application) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) SendStorageBySocket(message notify.StorageMessage) + SendNotify(path string, message map[string]interface{}) } type notifyServer struct { db *gorm.DB } +func (i *notifyServer) SendNotify(path string, message map[string]interface{}) { + + msg := gosf.Message{} + msg.Body = message + msg.Success = true + msg.Text = path + + notify := notify.Message{} + notify.Path = path + notify.Msg = msg + + NotifyMsg <- notify + +} + func (i *notifyServer) SendStorageBySocket(message notify.StorageMessage) { body := make(map[string]interface{}) body["data"] = message From 3935489d8bb1b657a9ae4e41c10aba1ba93177bb Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Fri, 9 Sep 2022 04:12:34 +0100 Subject: [PATCH 06/21] add shell script --- build/sysroot/usr/share/casaos/shell/update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/sysroot/usr/share/casaos/shell/update.sh b/build/sysroot/usr/share/casaos/shell/update.sh index 380210524..c01abb4e8 100644 --- a/build/sysroot/usr/share/casaos/shell/update.sh +++ b/build/sysroot/usr/share/casaos/shell/update.sh @@ -9,4 +9,4 @@ ### -curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash \ No newline at end of file +curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash From 4f491fa22f1b7b6c10d1c842155a800fdad4ead3 Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Tue, 13 Sep 2022 07:22:24 +0100 Subject: [PATCH 07/21] add system notiry --- common/notify.go | 18 ++++++++++++++++++ route/route.go | 2 ++ route/v1/notiry.go | 6 ++++++ service/notify.go | 20 ++++++++++++++------ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/common/notify.go b/common/notify.go index 4a003d076..c36cea0c7 100644 --- a/common/notify.go +++ b/common/notify.go @@ -18,6 +18,7 @@ const ( type NotifyService interface { SendNotify(path string, message map[string]interface{}) error + SendSystemNotify(message map[string]interface{}) error } type notifyService struct { address string @@ -41,7 +42,24 @@ func (n *notifyService) SendNotify(path string, message map[string]interface{}) return nil } +func (n *notifyService) SendSystemNotify(message map[string]interface{}) error { + url := strings.TrimSuffix(n.address, "/") + "/" + APICasaOSNotify + body, err := json.Marshal(message) + if err != nil { + return err + } + response, err := http.Post(url, "application/json", bytes.NewBuffer(body)) + if err != nil { + return err + } + + if response.StatusCode != http.StatusCreated { + return errors.New("failed to send notify (status code: " + fmt.Sprint(response.StatusCode) + ")") + } + return nil + +} func NewNotifyService(runtimePath string) (NotifyService, error) { casaosAddressFile := filepath.Join(runtimePath, CasaOSURLFilename) diff --git a/route/route.go b/route/route.go index 39d011b70..0bfcbfcc8 100644 --- a/route/route.go +++ b/route/route.go @@ -244,6 +244,8 @@ func InitRouter() *gin.Engine { v1NotifyGroup.Use() { v1NotifyGroup.POST("/:path", v1.PostNotifyMssage) + //merge to system + v1NotifyGroup.POST("", v1.PostSystemNotyfiy) } } return r diff --git a/route/v1/notiry.go b/route/v1/notiry.go index c818aab0d..54e86fd51 100644 --- a/route/v1/notiry.go +++ b/route/v1/notiry.go @@ -14,3 +14,9 @@ func PostNotifyMssage(c *gin.Context) { service.MyService.Notify().SendNotify(path, message) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } +func PostSystemNotyfiy(c *gin.Context) { + message := make(map[string]interface{}) + c.ShouldBind(&message) + service.MyService.Notify().SettingSystemTempData(message) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} diff --git a/service/notify.go b/service/notify.go index 154d45a4d..fe93d83af 100644 --- a/service/notify.go +++ b/service/notify.go @@ -38,14 +38,21 @@ type NotifyServer interface { SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) SendStorageBySocket(message notify.StorageMessage) SendNotify(path string, message map[string]interface{}) + SettingSystemTempData(message map[string]interface{}) } type notifyServer struct { - db *gorm.DB + db *gorm.DB + SystemTempMap map[string]interface{} } -func (i *notifyServer) SendNotify(path string, message map[string]interface{}) { +func (i *notifyServer) SettingSystemTempData(message map[string]interface{}) { + for k, v := range message { + i.SystemTempMap[k] = v + } +} +func (i *notifyServer) SendNotify(path string, message map[string]interface{}) { msg := gosf.Message{} msg.Body = message msg.Success = true @@ -77,9 +84,6 @@ func (i *notifyServer) SendStorageBySocket(message notify.StorageMessage) { func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) { body := make(map[string]interface{}) - body["sys_disk"] = disk - - body["sys_usb"] = list body["sys_mem"] = mem @@ -87,6 +91,10 @@ func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list [ body["sys_net"] = netList + for k, v := range i.SystemTempMap { + body[k] = v + } + msg := gosf.Message{} msg.Body = body msg.Success = true @@ -470,5 +478,5 @@ func SendMeg() { // } func NewNotifyService(db *gorm.DB) NotifyServer { - return ¬ifyServer{db: db} + return ¬ifyServer{db: db, SystemTempMap: make(map[string]interface{})} } From 8113f51cf7aa1a8f1ff09eec36cd07862638411b Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Thu, 15 Sep 2022 08:13:07 +0100 Subject: [PATCH 08/21] remove disk and test common package --- common/notify.go | 14 +- common/notify_test.go | 29 ++ go.mod | 1 - go.sum | 2 - main.go | 3 +- model/disk.go | 98 ------- model/docker.go | 4 + model/receive/app.go | 1 - pkg/sqlite/db.go | 2 +- route/init.go | 46 --- route/periodical.go | 265 +++-------------- route/route.go | 47 +-- route/v1/app.go | 53 ++++ route/v1/disk.go | 622 ---------------------------------------- route/v1/file.go | 27 +- route/v1/notiry.go | 5 +- route/v1/storage.go | 109 ------- route/v1/system.go | 147 +--------- service/disk.go | 285 ------------------ service/docker.go | 74 +++-- service/model/o_disk.go | 25 -- service/notify.go | 38 +-- service/service.go | 7 - 23 files changed, 190 insertions(+), 1714 deletions(-) create mode 100644 common/notify_test.go delete mode 100644 model/disk.go delete mode 100644 model/receive/app.go delete mode 100644 route/v1/disk.go delete mode 100644 route/v1/storage.go delete mode 100644 service/disk.go delete mode 100644 service/model/o_disk.go diff --git a/common/notify.go b/common/notify.go index c36cea0c7..82d339407 100644 --- a/common/notify.go +++ b/common/notify.go @@ -13,12 +13,12 @@ import ( const ( CasaOSURLFilename = "casaos.url" - APICasaOSNotify = "/v1/notiry" + APICasaOSNotify = "/v1/notify" ) type NotifyService interface { SendNotify(path string, message map[string]interface{}) error - SendSystemNotify(message map[string]interface{}) error + SendSystemStatusNotify(message map[string]interface{}) error } type notifyService struct { address string @@ -26,7 +26,7 @@ type notifyService struct { func (n *notifyService) SendNotify(path string, message map[string]interface{}) error { - url := strings.TrimSuffix(n.address, "/") + "/" + APICasaOSNotify + "/" + path + url := strings.TrimSuffix(n.address, "/") + APICasaOSNotify + "/" + path body, err := json.Marshal(message) if err != nil { return err @@ -42,9 +42,13 @@ func (n *notifyService) SendNotify(path string, message map[string]interface{}) return nil } -func (n *notifyService) SendSystemNotify(message map[string]interface{}) error { - url := strings.TrimSuffix(n.address, "/") + "/" + APICasaOSNotify +// disk: "sys_disk":{"size":56866869248,"avail":5855485952,"health":true,"used":48099700736} +// usb: "sys_usb":[{"name": "sdc","size": 7747397632,"model": "DataTraveler_2.0","avail": 7714418688,"children": null}] +func (n *notifyService) SendSystemStatusNotify(message map[string]interface{}) error { + + url := strings.TrimSuffix(n.address, "/") + APICasaOSNotify + "/system_status" + fmt.Println(url) body, err := json.Marshal(message) if err != nil { return err diff --git a/common/notify_test.go b/common/notify_test.go new file mode 100644 index 000000000..1e9c54389 --- /dev/null +++ b/common/notify_test.go @@ -0,0 +1,29 @@ +package common + +import "testing" + +func TestSendNotify(t *testing.T) { + notify, err := NewNotifyService("/var/run/casaos") + if err != nil { + t.Fatal(err) + } + err = notify.SendNotify("test", map[string]interface{}{ + "test": "test", + }) + if err != nil { + t.Fatal(err) + } +} + +func TestSendSystemStatusNotify(t *testing.T) { + notify, err := NewNotifyService("/var/run/casaos") + if err != nil { + t.Fatal(err) + } + err = notify.SendSystemStatusNotify(map[string]interface{}{ + "sys_usb": `[{"name": "sdc","size": 7747397632,"model": "DataTraveler_2.0","avail": 7714418688,"children": null}]`, + }) + if err != nil { + t.Fatal(err) + } +} diff --git a/go.mod b/go.mod index 6209c3e2d..cfcc59bba 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,6 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/pilebones/go-udev v0.9.0 github.com/pkg/errors v0.9.1 github.com/robfig/cron v1.2.0 github.com/satori/go.uuid v1.2.0 diff --git a/go.sum b/go.sum index 9e68d0ead..49a1770f2 100644 --- a/go.sum +++ b/go.sum @@ -814,8 +814,6 @@ github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZO github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q= -github.com/pilebones/go-udev v0.9.0/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/main.go b/main.go index 6ff7af859..f02afcab8 100644 --- a/main.go +++ b/main.go @@ -80,7 +80,6 @@ func main() { return } go route.SocketInit(service.NotifyMsg) - go route.MonitoryUSB() //model.Setup() //gredis.Setup() @@ -110,7 +109,7 @@ func main() { if err != nil { panic(err) } - routers := []string{"sys", "apps", "container", "app-categories", "port", "file", "folder", "batch", "image", "disks", "storage", "samba", "notify"} + routers := []string{"sys", "apps", "container", "app-categories", "port", "file", "folder", "batch", "image", "samba", "notify"} for _, v := range routers { err = service.MyService.Gateway().CreateRoute(&common.Route{ Path: "/v1/" + v, diff --git a/model/disk.go b/model/disk.go deleted file mode 100644 index 75d3bc519..000000000 --- a/model/disk.go +++ /dev/null @@ -1,98 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-07-13 10:43:45 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-08-03 14:45:35 - * @FilePath: /CasaOS/model/disk.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package model - -type LSBLKModel struct { - Name string `json:"name"` - FsType string `json:"fstype"` - Size uint64 `json:"size"` - FSSize string `json:"fssize"` - Path string `json:"path"` - Model string `json:"model"` //设备标识符 - RM bool `json:"rm"` //是否为可移动设备 - RO bool `json:"ro"` //是否为只读设备 - State string `json:"state"` - PhySec int `json:"phy-sec"` //物理扇区大小 - Type string `json:"type"` - Vendor string `json:"vendor"` //供应商 - Rev string `json:"rev"` //修订版本 - FSAvail string `json:"fsavail"` //可用空间 - FSUse string `json:"fsuse%"` //已用百分比 - MountPoint string `json:"mountpoint"` - Format string `json:"format"` - Health string `json:"health"` - HotPlug bool `json:"hotplug"` - UUID string `json:"uuid"` - FSUsed string `json:"fsused"` - Temperature int `json:"temperature"` - Tran string `json:"tran"` - MinIO uint64 `json:"min-io"` - UsedPercent float64 `json:"used_percent"` - Serial string `json:"serial"` - Children []LSBLKModel `json:"children"` - SubSystems string `json:"subsystems"` - Label string `json:"label"` - //详情特有 - StartSector uint64 `json:"start_sector,omitempty"` - Rota bool `json:"rota"` //true(hhd) false(ssd) - DiskType string `json:"disk_type"` - EndSector uint64 `json:"end_sector,omitempty"` -} - -type Drive struct { - Name string `json:"name"` - Size uint64 `json:"size"` - Model string `json:"model"` - Health string `json:"health"` - Temperature int `json:"temperature"` - DiskType string `json:"disk_type"` - NeedFormat bool `json:"need_format"` - Serial string `json:"serial"` - Path string `json:"path"` - ChildrenNumber int `json:"children_number"` -} - -type DriveUSB struct { - Name string `json:"name"` - Size uint64 `json:"size"` - Model string `json:"model"` - Avail uint64 `json:"avail"` - Children []USBChildren `json:"children"` -} -type USBChildren struct { - Name string `json:"name"` - Size uint64 `json:"size"` - Avail uint64 `json:"avail"` - MountPoint string `json:"mount_point"` -} - -type Storage struct { - MountPoint string `json:"mount_point"` - Size string `json:"size"` - Avail string `json:"avail"` //可用空间 - Type string `json:"type"` - Path string `json:"path"` - DriveName string `json:"drive_name"` - Label string `json:"label"` -} -type Storages struct { - DiskName string `json:"disk_name"` - Size uint64 `json:"size"` - Path string `json:"path"` - Children []Storage `json:"children"` -} - -type Summary struct { - Size uint64 `json:"size"` - Avail uint64 `json:"avail"` //可用空间 - Health bool `json:"health"` - Used uint64 `json:"used"` -} diff --git a/model/docker.go b/model/docker.go index a08331961..20b68cc5c 100644 --- a/model/docker.go +++ b/model/docker.go @@ -16,3 +16,7 @@ type DockerStatsModel struct { Data interface{} `json:"data"` Previous interface{} `json:"previous"` } + +type DeckerDaemonModel struct { + Graph string `json:"graph"` +} diff --git a/model/receive/app.go b/model/receive/app.go deleted file mode 100644 index 3ccae50e5..000000000 --- a/model/receive/app.go +++ /dev/null @@ -1 +0,0 @@ -package receive diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index 819da6555..e5d759536 100644 --- a/pkg/sqlite/db.go +++ b/pkg/sqlite/db.go @@ -43,7 +43,7 @@ func GetDb(dbPath string) *gorm.DB { } gdb = db - err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.SharesDBModel{}, model2.ConnectionsDBModel{}) + err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, model2.SharesDBModel{}, model2.ConnectionsDBModel{}) db.Exec("DROP TABLE IF EXISTS o_application") db.Exec("DROP TABLE IF EXISTS o_friend") db.Exec("DROP TABLE IF EXISTS o_person_download") diff --git a/route/init.go b/route/init.go index e2d09c788..a35de298e 100644 --- a/route/init.go +++ b/route/init.go @@ -3,65 +3,19 @@ package route import ( "fmt" "os" - "strconv" "strings" "time" - "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/samba" - "github.com/IceWhaleTech/CasaOS/pkg/utils/command" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" "go.uber.org/zap" ) func InitFunction() { - CheckSerialDiskMount() go InitNetworkMount() } - -func CheckSerialDiskMount() { - // check mount point - dbList := service.MyService.Disk().GetSerialAll() - - list := service.MyService.Disk().LSBLK(true) - mountPoint := make(map[string]string, len(dbList)) - //remount - for _, v := range dbList { - mountPoint[v.UUID] = v.MountPoint - } - for _, v := range list { - command.ExecEnabledSMART(v.Path) - if v.Children != nil { - for _, h := range v.Children { - //if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" { - if m, ok := mountPoint[h.UUID]; ok { - //mount point check - volume := m - if !file.CheckNotExist(m) { - for i := 0; file.CheckNotExist(volume); i++ { - volume = m + strconv.Itoa(i+1) - } - } - service.MyService.Disk().MountDisk(h.Path, volume) - if volume != m { - ms := model2.SerialDisk{} - ms.UUID = v.UUID - ms.MountPoint = volume - service.MyService.Disk().UpdateMountPoint(ms) - } - - } - //} - } - } - } - service.MyService.Disk().RemoveLSBLKCache() - command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;AutoRemoveUnuseDir") -} - func InitNetworkMount() { time.Sleep(time.Second * 10) connections := service.MyService.Connections().GetConnectionsList() diff --git a/route/periodical.go b/route/periodical.go index 6fbdd74ff..7d12ca2b4 100644 --- a/route/periodical.go +++ b/route/periodical.go @@ -14,20 +14,12 @@ package route import ( - "os" - "os/signal" - "reflect" - "strconv" "strings" - "syscall" "time" "unsafe" "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/IceWhaleTech/CasaOS/service" - "github.com/pilebones/go-udev/netlink" - "go.uber.org/zap" ) func SendNetINfoBySocket() { @@ -61,104 +53,6 @@ func SendMemBySocket() { service.MyService.Notify().SendMemInfoBySocket(service.MyService.System().GetMemInfo()) } -func SendDiskBySocket() { - list := service.MyService.Disk().LSBLK(true) - - summary := model.Summary{} - healthy := true - findSystem := 0 - - for i := 0; i < len(list); i++ { - if len(list[i].Children) > 0 && findSystem == 0 { - - for j := 0; j < len(list[i].Children); j++ { - - if len(list[i].Children[j].Children) > 0 { - for _, v := range list[i].Children[j].Children { - if v.MountPoint == "/" { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } else { - if list[i].Children[j].MountPoint == "/" { - s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64) - a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64) - u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } - - } - if findSystem == 1 { - findSystem += 1 - continue - } - if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") { - temp := service.MyService.Disk().SmartCTL(list[i].Path) - if reflect.DeepEqual(temp, model.SmartctlA{}) { - healthy = true - } else { - healthy = temp.SmartStatus.Passed - } - - //list[i].Temperature = temp.Temperature.Current - - if len(list[i].Children) > 0 { - for _, v := range list[i].Children { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - } - } - - } - } - - summary.Health = healthy - service.MyService.Notify().SendDiskInfoBySocket(summary) -} - -func SendUSBBySocket() { - usbList := service.MyService.Disk().LSBLK(false) - usb := []model.DriveUSB{} - for _, v := range usbList { - if v.Tran == "usb" { - isMount := false - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - isMount = true - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - - } - } - if isMount { - usb = append(usb, temp) - } - } - } - service.MyService.Notify().SendUSBInfoBySocket(usb) -} - func SendAllHardwareStatusBySocket() { netList := service.MyService.System().GetNetInfo() @@ -183,131 +77,44 @@ func SendAllHardwareStatusBySocket() { cpuData["temperature"] = service.MyService.System().GetCPUTemperature() cpuData["power"] = service.MyService.System().GetCPUPower() - list := service.MyService.Disk().LSBLK(true) - - summary := model.Summary{} - healthy := true - findSystem := 0 - - for i := 0; i < len(list); i++ { - if len(list[i].Children) > 0 && findSystem == 0 { - - for j := 0; j < len(list[i].Children); j++ { - - if len(list[i].Children[j].Children) > 0 { - for _, v := range list[i].Children[j].Children { - if v.MountPoint == "/" { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } else { - if list[i].Children[j].MountPoint == "/" { - s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64) - a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64) - u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } - - } - if findSystem == 1 { - findSystem += 1 - continue - } - if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") { - temp := service.MyService.Disk().SmartCTL(list[i].Path) - if reflect.DeepEqual(temp, model.SmartctlA{}) { - healthy = true - } else { - healthy = temp.SmartStatus.Passed - } - if len(list[i].Children) > 0 { - for _, v := range list[i].Children { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - summary.Size += s - summary.Avail += a - summary.Used += u - } - } - - } - } - - summary.Health = healthy - - usbList := service.MyService.Disk().LSBLK(false) - usb := []model.DriveUSB{} - for _, v := range usbList { - if v.Tran == "usb" { - isMount := false - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - isMount = true - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - } - } - if isMount { - usb = append(usb, temp) - } - - } - } memInfo := service.MyService.System().GetMemInfo() - service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memInfo, cpuData, newNet) + service.MyService.Notify().SendAllHardwareStatusBySocket(memInfo, cpuData, newNet) } -func MonitoryUSB() { - var matcher netlink.Matcher - - conn := new(netlink.UEventConn) - if err := conn.Connect(netlink.UdevEvent); err != nil { - loger.Error("udev err", zap.Any("Unable to connect to Netlink Kobject UEvent socket", err)) - } - defer conn.Close() - - queue := make(chan netlink.UEvent) - errors := make(chan error) - quit := conn.Monitor(queue, errors, matcher) - signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) - go func() { - <-signals - close(quit) - os.Exit(0) - }() - - for { - select { - case uevent := <-queue: - if uevent.Env["DEVTYPE"] == "disk" { - time.Sleep(time.Microsecond * 500) - SendUSBBySocket() - continue - } - case err := <-errors: - loger.Error("udev err", zap.Any("err", err)) - } - } - -} +// func MonitoryUSB() { +// var matcher netlink.Matcher + +// conn := new(netlink.UEventConn) +// if err := conn.Connect(netlink.UdevEvent); err != nil { +// loger.Error("udev err", zap.Any("Unable to connect to Netlink Kobject UEvent socket", err)) +// } +// defer conn.Close() + +// queue := make(chan netlink.UEvent) +// errors := make(chan error) +// quit := conn.Monitor(queue, errors, matcher) + +// signals := make(chan os.Signal, 1) +// signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) +// go func() { +// <-signals +// close(quit) +// os.Exit(0) +// }() + +// for { +// select { +// case uevent := <-queue: +// if uevent.Env["DEVTYPE"] == "disk" { +// time.Sleep(time.Microsecond * 500) +// SendUSBBySocket() +// continue +// } +// case err := <-errors: +// loger.Error("udev err", zap.Any("err", err)) +// } +// } + +// } diff --git a/route/route.go b/route/route.go index 0bfcbfcc8..110fd6992 100644 --- a/route/route.go +++ b/route/route.go @@ -1,7 +1,7 @@ package route import ( - jwt2 "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" + "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" "github.com/IceWhaleTech/CasaOS/middleware" "github.com/IceWhaleTech/CasaOS/pkg/config" v1 "github.com/IceWhaleTech/CasaOS/route/v1" @@ -45,7 +45,7 @@ func InitRouter() *gin.Engine { }) v1Group := r.Group("/v1") - v1Group.Use(jwt2.JWT()) + v1Group.Use(jwt.ExceptLocalhost()) { // v1UsersGroup := v1Group.Group("/users") // v1UsersGroup.Use() @@ -79,6 +79,7 @@ func InitRouter() *gin.Engine { v1ContainerGroup := v1Group.Group("/container") v1ContainerGroup.Use() { + v1ContainerGroup.GET("", v1.MyAppList) ///my/list v1ContainerGroup.GET("/usage", v1.AppUsageList) v1ContainerGroup.GET("/:id", v1.ContainerUpdateInfo) ///update/:id/info @@ -99,6 +100,8 @@ func InitRouter() *gin.Engine { v1ContainerGroup.PUT("/:id/latest", v1.PutAppUpdate) //Not used v1ContainerGroup.POST("/share", v1.ShareAppFile) + v1ContainerGroup.GET("/info", v1.GetcontainerInfo) + v1ContainerGroup.PUT("/info", v1.PutcontainerInfo) } v1AppCategoriesGroup := v1Group.Group("/app-categories") @@ -185,42 +188,6 @@ func InitRouter() *gin.Engine { { v1ImageGroup.GET("", v1.GetFileImage) } - - v1DisksGroup := v1Group.Group("/disks") - v1DisksGroup.Use() - { - //v1DiskGroup.GET("/check", v1.GetDiskCheck) //delete - //v1DisksGroup.GET("", v1.GetDiskInfo) - - //v1DisksGroup.POST("", v1.PostMountDisk) - v1DisksGroup.GET("", v1.GetDiskList) - v1DisksGroup.GET("/usb", v1.GetDisksUSBList) - v1DisksGroup.DELETE("/usb", v1.DeleteDiskUSB) - v1DisksGroup.DELETE("", v1.DeleteDisksUmount) - // //format storage - // v1DiskGroup.POST("/format", v1.PostDiskFormat) - - // //mount SATA disk - // v1DiskGroup.POST("/mount", v1.PostMountDisk) - - // //umount sata disk - // v1DiskGroup.POST("/umount", v1.PostDiskUmount) - - //v1DiskGroup.GET("/type", v1.FormatDiskType)//delete - - v1DisksGroup.DELETE("/part", v1.RemovePartition) //disk/delpart - } - - v1StorageGroup := v1Group.Group("/storage") - v1StorageGroup.Use() - { - v1StorageGroup.POST("", v1.PostDiskAddPartition) - - v1StorageGroup.PUT("", v1.PostDiskFormat) - - v1StorageGroup.DELETE("", v1.PostDiskUmount) - v1StorageGroup.GET("", v1.GetStorageList) - } v1SambaGroup := v1Group.Group("/samba") v1SambaGroup.Use() { @@ -243,9 +210,9 @@ func InitRouter() *gin.Engine { v1NotifyGroup := v1Group.Group("/notify") v1NotifyGroup.Use() { - v1NotifyGroup.POST("/:path", v1.PostNotifyMssage) + v1NotifyGroup.POST("/:path", v1.PostNotifyMessage) //merge to system - v1NotifyGroup.POST("", v1.PostSystemNotyfiy) + v1NotifyGroup.POST("/system_status", v1.PostSystemStatusNotify) } } return r diff --git a/route/v1/app.go b/route/v1/app.go index 1a9f2786e..cc2ee009d 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -2,10 +2,12 @@ package v1 import ( "encoding/json" + "fmt" "io/ioutil" "strconv" "github.com/IceWhaleTech/CasaOS/model" + "github.com/IceWhaleTech/CasaOS/pkg/utils/command" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" @@ -262,3 +264,54 @@ func ShareAppFile(c *gin.Context) { content := service.MyService.Casa().ShareAppFile(str) c.JSON(common_err.SUCCESS, json.RawMessage(content)) } + +func GetcontainerInfo(c *gin.Context) { + // info, err := service.MyService.Docker().GetDockerInfo() + // if err != nil { + // c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + // return + // } + daemon := model.DeckerDaemonModel{} + data := make(map[string]interface{}, 1) + data["docker_root_dir"] = "" + if file.Exists("/etc/docker/daemon.json") { + byteResult := file.ReadFullFile("/etc/docker/daemon.json") + err := json.Unmarshal(byteResult, &daemon) + if err != nil { + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + return + } + data["docker_root_dir"] = daemon.Graph + } + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) +} +func PutcontainerInfo(c *gin.Context) { + js := make(map[string]interface{}) + err := c.BindJSON(&js) + if err != nil { + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + return + } + dockerRootDir := js["docker_root_dir"].(string) + daemon := model.DeckerDaemonModel{} + if file.Exists("/etc/docker/daemon.json") { + byteResult := file.ReadFullFile("/etc/docker/daemon.json") + err := json.Unmarshal(byteResult, &daemon) + if err != nil { + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + return + } + } + if !file.Exists(dockerRootDir) { + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS), Data: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) + return + } + daemon.Graph = dockerRootDir + byteMode, _ := json.Marshal(daemon) + file.WriteToPath(byteMode, "/etc/docker", "daemon.json") + + fmt.Println(command.ExecResultStr("systemctl daemon-reload")) + fmt.Println(command.ExecResultStr("systemctl restart docker")) + + c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: js}) +} diff --git a/route/v1/disk.go b/route/v1/disk.go deleted file mode 100644 index e72e3ff4a..000000000 --- a/route/v1/disk.go +++ /dev/null @@ -1,622 +0,0 @@ -package v1 - -import ( - "fmt" - "net/http" - "path/filepath" - "reflect" - "strconv" - "strings" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/model/notify" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - - "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/gin-gonic/gin" - "github.com/shirou/gopsutil/v3/disk" -) - -var diskMap = make(map[string]string) - -// @Summary disk list -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/list [get] -func GetDiskList(c *gin.Context) { - path := c.Query("path") - if len(path) > 0 { - m := service.MyService.Disk().GetDiskInfo(path) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m}) - return - } - t := c.DefaultQuery("type", "") - list := service.MyService.Disk().LSBLK(false) - if t == "usb" { - data := []model.DriveUSB{} - for _, v := range list { - if v.Tran == "usb" { - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - } - } - data = append(data, temp) - } - } - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) - return - } - - dbList := service.MyService.Disk().GetSerialAll() - part := make(map[string]int64, len(dbList)) - for _, v := range dbList { - part[v.MountPoint] = v.CreatedAt - } - findSystem := 0 - - disks := []model.Drive{} - storage := []model.Storage{} - avail := []model.Drive{} - for i := 0; i < len(list); i++ { - disk := model.Drive{} - if list[i].Rota { - disk.DiskType = "HDD" - } else { - disk.DiskType = "SSD" - } - disk.Serial = list[i].Serial - disk.Name = list[i].Name - disk.Size = list[i].Size - disk.Path = list[i].Path - disk.Model = list[i].Model - disk.ChildrenNumber = len(list[i].Children) - if len(list[i].Children) > 0 && findSystem == 0 { - for j := 0; j < len(list[i].Children); j++ { - if len(list[i].Children[j].Children) > 0 { - for _, v := range list[i].Children[j].Children { - if v.MountPoint == "/" { - stor := model.Storage{} - stor.MountPoint = v.MountPoint - stor.Size = v.FSSize - stor.Avail = v.FSAvail - stor.Path = v.Path - stor.Type = v.FsType - stor.DriveName = "System" - disk.Model = "System" - if strings.Contains(v.SubSystems, "mmc") { - disk.DiskType = "MMC" - } else if strings.Contains(v.SubSystems, "usb") { - disk.DiskType = "USB" - } - disk.Health = "true" - - disks = append(disks, disk) - storage = append(storage, stor) - findSystem = 1 - break - } - } - } else { - if list[i].Children[j].MountPoint == "/" { - stor := model.Storage{} - stor.MountPoint = list[i].Children[j].MountPoint - stor.Size = list[i].Children[j].FSSize - stor.Avail = list[i].Children[j].FSAvail - stor.Path = list[i].Children[j].Path - stor.Type = list[i].Children[j].FsType - stor.DriveName = "System" - disk.Model = "System" - if strings.Contains(list[i].Children[j].SubSystems, "mmc") { - disk.DiskType = "MMC" - } else if strings.Contains(list[i].Children[j].SubSystems, "usb") { - disk.DiskType = "USB" - } - disk.Health = "true" - - disks = append(disks, disk) - storage = append(storage, stor) - findSystem = 1 - break - } - } - - } - } - if findSystem == 1 { - findSystem += 1 - continue - } - - if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") { - temp := service.MyService.Disk().SmartCTL(list[i].Path) - if reflect.DeepEqual(temp, model.SmartctlA{}) { - temp.SmartStatus.Passed = true - } - isAvail := true - for _, v := range list[i].Children { - if v.MountPoint != "" { - stor := model.Storage{} - stor.MountPoint = v.MountPoint - stor.Size = v.FSSize - stor.Avail = v.FSAvail - stor.Path = v.Path - stor.Type = v.FsType - stor.DriveName = list[i].Name - storage = append(storage, stor) - isAvail = false - } - } - - if isAvail { - //if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" { - disk.NeedFormat = false - avail = append(avail, disk) - // } else { - // disk.NeedFormat = true - // avail = append(avail, disk) - // } - } - - disk.Temperature = temp.Temperature.Current - disk.Health = strconv.FormatBool(temp.SmartStatus.Passed) - - disks = append(disks, disk) - } - } - data := make(map[string]interface{}, 3) - data["drive"] = disks - data["storage"] = storage - data["avail"] = avail - - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) -} - -// @Summary disk list -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/list [get] -func GetDisksUSBList(c *gin.Context) { - list := service.MyService.Disk().LSBLK(false) - data := []model.DriveUSB{} - for _, v := range list { - if v.Tran == "usb" { - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Label - if temp.Name == "" { - temp.Name = v.Name - } - temp.Size = v.Size - children := []model.USBChildren{} - for _, child := range v.Children { - - if len(child.MountPoint) > 0 { - tempChildren := model.USBChildren{} - tempChildren.MountPoint = child.MountPoint - tempChildren.Size, _ = strconv.ParseUint(child.FSSize, 10, 64) - tempChildren.Avail, _ = strconv.ParseUint(child.FSAvail, 10, 64) - tempChildren.Name = child.Label - if len(tempChildren.Name) == 0 { - tempChildren.Name = filepath.Base(child.MountPoint) - } - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - children = append(children, tempChildren) - temp.Avail += avail - } - } - - temp.Children = children - data = append(data, temp) - } - } - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) - -} - -func DeleteDisksUmount(c *gin.Context) { - js := make(map[string]string) - c.ShouldBind(&js) - - path := js["path"] - pwd := js["password"] - - if len(path) == 0 { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - token := c.GetHeader("Authorization") - if len(token) == 0 { - token = c.Query("token") - } - claims, err := jwt.ParseToken(token, true) - if err != nil { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if encryption.GetMD5ByStr(pwd) != claims.Password { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if _, ok := diskMap[path]; ok { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) - return - } - - diskInfo := service.MyService.Disk().GetDiskInfo(path) - for _, v := range diskInfo.Children { - service.MyService.Disk().UmountPointAndRemoveDir(v.Path) - //delete data - service.MyService.Disk().DeleteMountPoint(v.Path, v.MountPoint) - - service.MyService.Shares().DeleteShareByPath(v.MountPoint) - } - - service.MyService.Disk().RemoveLSBLKCache() - - //send notify to client - msg := notify.StorageMessage{} - msg.Action = "REMOVED" - msg.Path = path - msg.Volume = "" - msg.Size = 0 - msg.Type = "" - service.MyService.Notify().SendStorageBySocket(msg) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: path}) -} - -func DeleteDiskUSB(c *gin.Context) { - js := make(map[string]string) - c.ShouldBind(&js) - mountPoint := js["mount_point"] - if file.CheckNotExist(mountPoint) { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) - return - } - service.MyService.Disk().UmountUSB(mountPoint) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: mountPoint}) -} - -// @Summary get disk list -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/lists [get] -func GetPlugInDisks(c *gin.Context) { - - list := service.MyService.Disk().LSBLK(true) - var result []*disk.UsageStat - for _, item := range list { - result = append(result, service.MyService.Disk().GetDiskInfoByPath(item.Path)) - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result}) -} - -// @Summary disk detail -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Param path query string true "for example /dev/sda" -// @Success 200 {string} string "ok" -// @Router /disk/info [get] -func GetDiskInfo(c *gin.Context) { - path := c.Query("path") - if len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - } - m := service.MyService.Disk().GetDiskInfo(path) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: m}) -} - -// @Summary 获取支持的格式 -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/type [get] -func FormatDiskType(c *gin.Context) { - var strArr = [4]string{"fat32", "ntfs", "ext4", "exfat"} - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: strArr}) - -} - -// @Summary 删除分区 -// @Produce application/json -// @Accept multipart/form-data -// @Tags disk -// @Security ApiKeyAuth -// @Param path formData string true "磁盘路径 例如/dev/sda1" -// @Success 200 {string} string "ok" -// @Router /disk/delpart [delete] -func RemovePartition(c *gin.Context) { - js := make(map[string]string) - c.ShouldBind(&js) - path := js["path"] - - if len(path) == 0 { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - } - var p = path[:len(path)-1] - var n = path[len(path)-1:] - service.MyService.Disk().DelPartition(p, n) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary add storage -// @Produce application/json -// @Accept multipart/form-data -// @Tags disk -// @Security ApiKeyAuth -// @Param path formData string true "disk path e.g. /dev/sda" -// @Param serial formData string true "serial" -// @Param name formData string true "name" -// @Param format formData bool true "need format(true)" -// @Success 200 {string} string "ok" -// @Router /disk/storage [post] -func PostDiskAddPartition(c *gin.Context) { - - js := make(map[string]interface{}) - c.ShouldBind(&js) - path := js["path"].(string) - name := js["name"].(string) - format := js["format"].(bool) - - if len(path) == 0 { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if _, ok := diskMap[path]; ok { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) - return - } - - //diskInfo := service.MyService.Disk().GetDiskInfo(path) - - // if !file.CheckNotExist("/DATA/" + name) { - // // /mnt/name exist - // c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)}) - // return - // } - diskMap[path] = "busying" - currentDisk := service.MyService.Disk().GetDiskInfo(path) - if format { - // format := service.MyService.Disk().FormatDisk(path+"1", "ext4") - // if len(format) == 0 { - // delete(diskMap, path) - // c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)}) - // return - // } - service.MyService.Disk().AddPartition(path) - } - - // formatBool := true - // for formatBool { - // currentDisk = service.MyService.Disk().GetDiskInfo(path) - // if len(currentDisk.Children) > 0 { - // formatBool = false - // break - // } - // time.Sleep(time.Second) - // } - currentDisk = service.MyService.Disk().GetDiskInfo(path) - // if len(currentDisk.Children) != 1 { - // c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)}) - // return - // } - fmt.Println(name) - if len(name) == 0 { - name = "Storage" - } - fmt.Println(name) - for i := 0; i < len(currentDisk.Children); i++ { - childrenName := currentDisk.Children[i].Label - if len(childrenName) == 0 { - //childrenName = name + "_" + currentDisk.Children[i].Name - childrenName = name + "_" + strconv.Itoa(i+1) - } - mountPath := "/DATA/" + childrenName - if !file.CheckNotExist(mountPath) { - ls := service.MyService.System().GetDirPath(mountPath) - if len(ls) > 0 { - // exist - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)}) - return - } - } - m := model2.SerialDisk{} - m.MountPoint = mountPath - m.Path = currentDisk.Children[i].Path - m.UUID = currentDisk.Children[i].UUID - m.State = 0 - m.CreatedAt = time.Now().Unix() - service.MyService.Disk().SaveMountPoint(m) - //mount dir - service.MyService.Disk().MountDisk(currentDisk.Children[i].Path, mountPath) - } - - service.MyService.Disk().RemoveLSBLKCache() - - delete(diskMap, path) - - //send notify to client - msg := notify.StorageMessage{} - msg.Action = "ADDED" - msg.Path = currentDisk.Children[0].Path - msg.Volume = "/DATA/" - msg.Size = currentDisk.Children[0].Size - msg.Type = currentDisk.Children[0].Tran - service.MyService.Notify().SendStorageBySocket(msg) - - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Param pwd formData string true "user password" -// @Param volume formData string true "mount point" -// @Success 200 {string} string "ok" -// @Router /disk/format [post] -func PostDiskFormat(c *gin.Context) { - js := make(map[string]string) - c.ShouldBind(&js) - path := js["path"] - t := "ext4" - pwd := js["password"] - volume := js["volume"] - token := c.GetHeader("Authorization") - if len(token) == 0 { - token = c.Query("token") - } - claims, err := jwt.ParseToken(token, true) - if err != nil { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if encryption.GetMD5ByStr(pwd) != claims.Password { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if len(path) == 0 || len(t) == 0 { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if _, ok := diskMap[path]; ok { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) - return - } - diskMap[path] = "busying" - service.MyService.Disk().UmountPointAndRemoveDir(path) - format := service.MyService.Disk().FormatDisk(path, t) - if len(format) == 0 { - delete(diskMap, path) - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FORMAT_ERROR, Message: common_err.GetMsg(common_err.FORMAT_ERROR)}) - return - } - service.MyService.Disk().MountDisk(path, volume) - service.MyService.Disk().RemoveLSBLKCache() - delete(diskMap, path) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary remove mount point -// @Produce application/json -// @Accept multipart/form-data -// @Tags disk -// @Security ApiKeyAuth -// @Param path formData string true "e.g. /dev/sda1" -// @Param mount_point formData string true "e.g. /mnt/volume1" -// @Param pwd formData string true "user password" -// @Success 200 {string} string "ok" -// @Router /disk/umount [post] -func PostDiskUmount(c *gin.Context) { - js := make(map[string]string) - c.ShouldBind(&js) - - path := js["path"] - mountPoint := js["volume"] - pwd := js["password"] - - if len(path) == 0 || len(mountPoint) == 0 { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - token := c.GetHeader("Authorization") - if len(token) == 0 { - token = c.Query("token") - } - claims, err := jwt.ParseToken(token, true) - if err != nil { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if encryption.GetMD5ByStr(pwd) != claims.Password { - c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) - return - } - - if _, ok := diskMap[path]; ok { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) - return - } - - service.MyService.Disk().UmountPointAndRemoveDir(path) - //delete data - service.MyService.Disk().DeleteMountPoint(path, mountPoint) - service.MyService.Disk().RemoveLSBLKCache() - - //send notify to client - msg := notify.StorageMessage{} - msg.Action = "REMOVED" - msg.Path = path - msg.Volume = mountPoint - msg.Size = 0 - msg.Type = "" - service.MyService.Notify().SendStorageBySocket(msg) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary confirm delete disk -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Param id path string true "id" -// @Success 200 {string} string "ok" -// @Router /disk/remove/{id} [delete] -func DeleteDisk(c *gin.Context) { - id := c.Param("id") - service.MyService.Disk().DeleteMount(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary check mount point -// @Produce application/json -// @Accept application/json -// @Tags disk -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /disk/init [get] -func GetDiskCheck(c *gin.Context) { - - dbList := service.MyService.Disk().GetSerialAll() - list := service.MyService.Disk().LSBLK(true) - - mapList := make(map[string]string) - - for _, v := range list { - mapList[v.Serial] = "1" - } - - for _, v := range dbList { - if _, ok := mapList[v.UUID]; !ok { - //disk undefind - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: "disk undefind"}) - return - } - } - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} diff --git a/route/v1/file.go b/route/v1/file.go index 0b2dbc75a..548ee4a0b 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -236,33 +236,8 @@ func DirPath(c *gin.Context) { info[i].Type = "application" } } - } else if path == "/DATA" { - disk := make(map[string]string) - lsblk := service.MyService.Disk().LSBLK(true) - for _, v := range lsblk { - if len(v.Children) > 0 { - t := v.Tran - for _, c := range v.Children { - if len(c.Children) > 0 { - for _, gc := range c.Children { - if len(gc.MountPoint) > 0 { - disk[gc.MountPoint] = t - } - } - } - if len(c.MountPoint) > 0 { - disk[c.MountPoint] = t - } - } - - } - } - for i := 0; i < len(info); i++ { - if v, ok := disk[info[i].Path]; ok { - info[i].Type = v - } - } } + for i := 0; i < len(info); i++ { if v, ok := sharesMap[info[i].Path]; ok { ex := make(map[string]interface{}) diff --git a/route/v1/notiry.go b/route/v1/notiry.go index 54e86fd51..eef2a1be2 100644 --- a/route/v1/notiry.go +++ b/route/v1/notiry.go @@ -7,14 +7,15 @@ import ( "github.com/gin-gonic/gin" ) -func PostNotifyMssage(c *gin.Context) { +func PostNotifyMessage(c *gin.Context) { path := c.Param("path") message := make(map[string]interface{}) c.ShouldBind(&message) service.MyService.Notify().SendNotify(path, message) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } -func PostSystemNotyfiy(c *gin.Context) { + +func PostSystemStatusNotify(c *gin.Context) { message := make(map[string]interface{}) c.ShouldBind(&message) service.MyService.Notify().SettingSystemTempData(message) diff --git a/route/v1/storage.go b/route/v1/storage.go deleted file mode 100644 index b6bb3e319..000000000 --- a/route/v1/storage.go +++ /dev/null @@ -1,109 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-07-11 16:02:29 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-08-17 19:14:50 - * @FilePath: /CasaOS/route/v1/storage.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "path/filepath" - "reflect" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - "github.com/gin-gonic/gin" -) - -func GetStorageList(c *gin.Context) { - system := c.Query("system") - storages := []model.Storages{} - disks := service.MyService.Disk().LSBLK(false) - diskNumber := 1 - children := 1 - findSystem := 0 - for _, d := range disks { - if d.Tran != "usb" { - tempSystemDisk := false - children = 1 - tempDisk := model.Storages{ - DiskName: d.Model, - Path: d.Path, - Size: d.Size, - } - - storageArr := []model.Storage{} - temp := service.MyService.Disk().SmartCTL(d.Path) - if reflect.DeepEqual(temp, model.SmartctlA{}) { - temp.SmartStatus.Passed = true - } - for _, v := range d.Children { - if v.MountPoint != "" { - if findSystem == 0 { - if v.MountPoint == "/" { - tempDisk.DiskName = "System" - findSystem = 1 - tempSystemDisk = true - } - if len(v.Children) > 0 { - for _, c := range v.Children { - if c.MountPoint == "/" { - tempDisk.DiskName = "System" - findSystem = 1 - tempSystemDisk = true - break - } - } - } - } - - stor := model.Storage{} - stor.MountPoint = v.MountPoint - stor.Size = v.FSSize - stor.Avail = v.FSAvail - stor.Path = v.Path - stor.Type = v.FsType - stor.DriveName = v.Name - if len(v.Label) == 0 { - if stor.MountPoint == "/" { - stor.Label = "System" - } else { - stor.Label = filepath.Base(stor.MountPoint) - } - - children += 1 - } else { - stor.Label = v.Label - } - storageArr = append(storageArr, stor) - } - } - - if len(storageArr) > 0 { - if tempSystemDisk && len(system) > 0 { - tempStorageArr := []model.Storage{} - for i := 0; i < len(storageArr); i++ { - if storageArr[i].MountPoint != "/boot/efi" && storageArr[i].Type != "swap" { - tempStorageArr = append(tempStorageArr, storageArr[i]) - } - } - tempDisk.Children = tempStorageArr - storages = append(storages, tempDisk) - diskNumber += 1 - } else if !tempSystemDisk { - tempDisk.Children = storageArr - storages = append(storages, tempDisk) - diskNumber += 1 - } - - } - } - } - - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storages}) -} diff --git a/route/v1/system.go b/route/v1/system.go index 9f908d262..29fbcf21d 100644 --- a/route/v1/system.go +++ b/route/v1/system.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "net/http" "os" - "reflect" "strconv" "strings" "time" @@ -16,14 +15,12 @@ import ( "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" "github.com/IceWhaleTech/CasaOS/pkg/utils/version" "github.com/IceWhaleTech/CasaOS/service" model2 "github.com/IceWhaleTech/CasaOS/service/model" "github.com/IceWhaleTech/CasaOS/types" "github.com/gin-gonic/gin" - "go.uber.org/zap" ) // @Summary check version @@ -79,7 +76,7 @@ func GetCasaOSErrorLogs(c *gin.Context) { c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: service.MyService.System().GetCasaOSLogs(line)}) } -//系统配置 +// 系统配置 func GetSystemConfigDebug(c *gin.Context) { array := service.MyService.System().GetSystemConfigDebug() disk := service.MyService.System().GetDiskInfo() @@ -185,31 +182,6 @@ func PutSystemUSBAutoMount(c *gin.Context) { service.MyService.System().UpdateUSBAutoMount("False") service.MyService.System().ExecUSBAutoMountShell("False") } - go func() { - usbList := service.MyService.Disk().LSBLK(false) - usb := []model.DriveUSB{} - for _, v := range usbList { - if v.Tran == "usb" { - isMount := false - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - isMount = true - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - - } - } - if isMount { - usb = append(usb, temp) - } - } - } - service.MyService.Notify().SendUSBInfoBySocket(usb) - }() c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, @@ -229,31 +201,6 @@ func GetSystemUSBAutoMount(c *gin.Context) { if config.ServerInfo.USBAutoMount == "False" { state = "False" } - go func() { - usbList := service.MyService.Disk().LSBLK(false) - usb := []model.DriveUSB{} - for _, v := range usbList { - if v.Tran == "usb" { - isMount := false - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - isMount = true - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - - } - } - if isMount { - usb = append(usb, temp) - } - } - } - service.MyService.Notify().SendUSBInfoBySocket(usb) - }() c.JSON(common_err.SUCCESS, model.Result{ Success: common_err.SUCCESS, @@ -324,98 +271,6 @@ func GetSystemHardwareInfo(c *gin.Context) { // @Router /sys/utilization [get] func GetSystemUtilization(c *gin.Context) { var data = make(map[string]interface{}, 6) - - list := service.MyService.Disk().LSBLK(true) - - summary := model.Summary{} - healthy := true - findSystem := 0 - - for i := 0; i < len(list); i++ { - if len(list[i].Children) > 0 && findSystem == 0 { - - for j := 0; j < len(list[i].Children); j++ { - - if len(list[i].Children[j].Children) > 0 { - for _, v := range list[i].Children[j].Children { - if v.MountPoint == "/" { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - loger.Info("disk info", zap.Any("/ total:", s)) - loger.Info("disk path", zap.Any("path", v.Path)) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } else { - if list[i].Children[j].MountPoint == "/" { - s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64) - a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64) - u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64) - loger.Info("disk info", zap.Any("/ total:", s)) - loger.Info("disk path", zap.Any("path", list[i].Path)) - summary.Size += s - summary.Avail += a - summary.Used += u - findSystem = 1 - break - } - } - } - - } - if findSystem == 1 { - findSystem += 1 - continue - } - if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" || strings.Contains(list[i].SubSystems, "virtio") || (list[i].Tran == "ata" && list[i].Type == "disk") { - temp := service.MyService.Disk().SmartCTL(list[i].Path) - if reflect.DeepEqual(temp, model.SmartctlA{}) { - healthy = true - } else { - healthy = temp.SmartStatus.Passed - } - if len(list[i].Children) > 0 { - for _, v := range list[i].Children { - s, _ := strconv.ParseUint(v.FSSize, 10, 64) - a, _ := strconv.ParseUint(v.FSAvail, 10, 64) - u, _ := strconv.ParseUint(v.FSUsed, 10, 64) - loger.Info("disk info", zap.Any("/ total:", s)) - loger.Info("disk path", zap.Any("path", list[i].Path)) - summary.Size += s - summary.Avail += a - summary.Used += u - } - } - - } - } - - summary.Health = healthy - data["disk"] = summary - usbList := service.MyService.Disk().LSBLK(false) - usb := []model.DriveUSB{} - for _, v := range usbList { - if v.Tran == "usb" { - temp := model.DriveUSB{} - temp.Model = v.Model - temp.Name = v.Name - temp.Size = v.Size - - for _, child := range v.Children { - if len(child.MountPoint) > 0 { - avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) - temp.Avail += avail - } - } - usb = append(usb, temp) - } - } - data["usb"] = usb cpu := service.MyService.System().GetCpuPercent() num := service.MyService.System().GetCpuCoreNum() cpuData := make(map[string]interface{}) diff --git a/service/disk.go b/service/disk.go deleted file mode 100644 index dfe8219bc..000000000 --- a/service/disk.go +++ /dev/null @@ -1,285 +0,0 @@ -package service - -import ( - json2 "encoding/json" - "fmt" - "reflect" - "strconv" - "strings" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/shirou/gopsutil/v3/disk" - "github.com/tidwall/gjson" - "go.uber.org/zap" - "gorm.io/gorm" -) - -type DiskService interface { - GetPlugInDisk() []string - LSBLK(isUseCache bool) []model.LSBLKModel - SmartCTL(path string) model.SmartctlA - FormatDisk(path, format string) []string - UmountPointAndRemoveDir(path string) []string - GetDiskInfo(path string) model.LSBLKModel - DelPartition(path, num string) string - AddPartition(path string) string - GetDiskInfoByPath(path string) *disk.UsageStat - MountDisk(path, volume string) - GetSerialAll() []model2.SerialDisk - SaveMountPoint(m model2.SerialDisk) - DeleteMountPoint(path, mountPoint string) - DeleteMount(id string) - UpdateMountPoint(m model2.SerialDisk) - RemoveLSBLKCache() - UmountUSB(path string) -} -type diskService struct { - db *gorm.DB -} - -func (d *diskService) RemoveLSBLKCache() { - key := "system_lsblk" - Cache.Delete(key) -} -func (d *diskService) UmountUSB(path string) { - r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;UDEVILUmount " + path) - fmt.Println(r) -} -func (d *diskService) SmartCTL(path string) model.SmartctlA { - - key := "system_smart_" + path - if result, ok := Cache.Get(key); ok { - - res, ok := result.(model.SmartctlA) - if ok { - return res - } - } - var m model.SmartctlA - str := command2.ExecSmartCTLByPath(path) - if str == nil { - loger.Error("failed to exec shell ", zap.Any("err", "smartctl exec error")) - Cache.Add(key, m, time.Minute*10) - return m - } - - err := json2.Unmarshal([]byte(str), &m) - if err != nil { - loger.Error("Failed to unmarshal json", zap.Any("err", err)) - } - if !reflect.DeepEqual(m, model.SmartctlA{}) { - Cache.Add(key, m, time.Hour*24) - } - return m -} - -//通过脚本获取外挂磁盘 -func (d *diskService) GetPlugInDisk() []string { - return command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetPlugInDisk") -} - -//格式化硬盘 -func (d *diskService) FormatDisk(path, format string) []string { - r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;FormatDisk " + path + " " + format) - return r -} - -//移除挂载点,删除目录 -func (d *diskService) UmountPointAndRemoveDir(path string) []string { - r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;UMountPorintAndRemoveDir " + path) - return r -} - -//删除分区 -func (d *diskService) DelPartition(path, num string) string { - r := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;DelPartition " + path + " " + num) - fmt.Println(r) - return "" -} - -//part -func (d *diskService) AddPartition(path string) string { - command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;AddPartition " + path) - return "" -} - -func (d *diskService) AddAllPartition(path string) { - -} - -//获取硬盘详情 -func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat { - diskInfo, err := disk.Usage(path + "1") - - if err != nil { - fmt.Println(err) - } - diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64) - diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64) - return diskInfo -} - -//get disk details -func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel { - key := "system_lsblk" - var n []model.LSBLKModel - - if result, ok := Cache.Get(key); ok && isUseCache { - - res, ok := result.([]model.LSBLKModel) - if ok { - return res - } - } - - str := command2.ExecLSBLK() - if str == nil { - loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error")) - return nil - } - var m []model.LSBLKModel - err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &m) - if err != nil { - loger.Error("Failed to unmarshal json", zap.Any("err", err)) - } - - var c []model.LSBLKModel - - var fsused uint64 - - var health = true - for _, i := range m { - if i.Type != "loop" && !i.RO { - fsused = 0 - for _, child := range i.Children { - if child.RM { - child.Health = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskHealthState " + child.Path)) - if strings.ToLower(strings.TrimSpace(child.State)) != "ok" { - health = false - } - f, _ := strconv.ParseUint(child.FSUsed, 10, 64) - fsused += f - } else { - health = false - } - c = append(c, child) - } - //i.Format = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskType " + i.Path)) - if health { - i.Health = "OK" - } - i.FSUsed = strconv.FormatUint(fsused, 10) - i.Children = c - if fsused > 0 { - i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64) - if err != nil { - loger.Error("Failed to parse float", zap.Any("err", err)) - } - } - n = append(n, i) - health = true - c = []model.LSBLKModel{} - fsused = 0 - } - } - if len(n) > 0 { - Cache.Add(key, n, time.Second*100) - } - return n -} - -func (d *diskService) GetDiskInfo(path string) model.LSBLKModel { - str := command2.ExecLSBLKByPath(path) - if str == nil { - loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error")) - return model.LSBLKModel{} - } - - var ml []model.LSBLKModel - err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml) - if err != nil { - loger.Error("Failed to unmarshal json", zap.Any("err", err)) - return model.LSBLKModel{} - } - - m := model.LSBLKModel{} - if len(ml) > 0 { - m = ml[0] - } - return m - // 下面为计算是否可以继续分区的部分,暂时不需要 - chiArr := make(map[string]string) - chiList := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetPartitionSectors " + m.Path) - if len(chiList) == 0 { - loger.Error("chiList length error", zap.Any("err", "chiList length error")) - } - for i := 0; i < len(chiList); i++ { - tempArr := strings.Split(chiList[i], ",") - chiArr[tempArr[0]] = chiList[i] - } - var maxSector uint64 = 0 - for i := 0; i < len(m.Children); i++ { - tempArr := strings.Split(chiArr[m.Children[i].Path], ",") - m.Children[i].StartSector, _ = strconv.ParseUint(tempArr[1], 10, 64) - m.Children[i].EndSector, _ = strconv.ParseUint(tempArr[2], 10, 64) - if m.Children[i].EndSector > maxSector { - maxSector = m.Children[i].EndSector - } - - } - diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskSizeAndSectors " + m.Path) - - if len(diskEndSector) < 2 { - loger.Error("diskEndSector length error", zap.Any("err", "diskEndSector length error")) - } - diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64) - if (diskEndSectorInt-maxSector)*m.MinIO/1024/1024 > 100 { - //添加可以分区情况 - p := model.LSBLKModel{} - p.Path = "可以添加" - m.Children = append(m.Children, p) - } - return m -} - -func (d *diskService) MountDisk(path, volume string) { - //fmt.Println("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume) - r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume) - fmt.Println(r) -} - -func (d *diskService) SaveMountPoint(m model2.SerialDisk) { - d.db.Where("uuid = ?", m.UUID).Delete(&model2.SerialDisk{}) - d.db.Create(&m) -} - -func (d *diskService) UpdateMountPoint(m model2.SerialDisk) { - d.db.Model(&model2.SerialDisk{}).Where("uui = ?", m.UUID).Update("mount_point", m.MountPoint) -} - -func (d *diskService) DeleteMount(id string) { - - d.db.Delete(&model2.SerialDisk{}).Where("id = ?", id) -} - -func (d *diskService) DeleteMountPoint(path, mountPoint string) { - - d.db.Where("path = ? AND mount_point = ?", path, mountPoint).Delete(&model2.SerialDisk{}) - - command2.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;do_umount " + path) -} - -func (d *diskService) GetSerialAll() []model2.SerialDisk { - var m []model2.SerialDisk - d.db.Find(&m) - return m -} - -func NewDiskService(db *gorm.DB) DiskService { - return &diskService{db: db} -} diff --git a/service/docker.go b/service/docker.go index 9fe885fd1..812fb8a39 100644 --- a/service/docker.go +++ b/service/docker.go @@ -59,6 +59,7 @@ type DockerService interface { DockerImageInfo(image string) (types.ImageInspect, error) GetNetWorkNameByNetWorkID(id string) (string, error) ContainerExecShell(container_id string) string + GetDockerInfo() (types.Info, error) } type dockerService struct { @@ -94,7 +95,7 @@ func (ds *dockerService) ContainerExecShell(container_id string) string { return exec.ID } -//创建默认网络 +// 创建默认网络 func DockerNetwork() { cli, _ := client2.NewClientWithOpts(client2.FromEnv) @@ -109,7 +110,7 @@ func DockerNetwork() { cli.NetworkCreate(context.Background(), docker.NETWORKNAME, types.NetworkCreate{}) } -//根据网络id获取网络名 +// 根据网络id获取网络名 func (ds *dockerService) GetNetWorkNameByNetWorkID(id string) (string, error) { cli, _ := client2.NewClientWithOpts(client2.FromEnv) defer cli.Close() @@ -122,7 +123,7 @@ func (ds *dockerService) GetNetWorkNameByNetWorkID(id string) (string, error) { return "", err } -//拉取镜像 +// 拉取镜像 func DockerPull() { cli, _ := client2.NewClientWithOpts(client2.FromEnv) @@ -141,7 +142,7 @@ func DockerPull() { } -//拉取镜像 +// 拉取镜像 func DockerEx() { cli, _ := client2.NewClientWithOpts(client2.FromEnv) @@ -292,7 +293,7 @@ func DockerLogs() { //正式内容 -//检查镜像是否存在 +// 检查镜像是否存在 func (ds *dockerService) IsExistImage(imageName string) bool { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -311,7 +312,7 @@ func (ds *dockerService) IsExistImage(imageName string) bool { return false } -//安装镜像 +// 安装镜像 func (ds *dockerService) DockerPullImage(imageName string, icon, name string) error { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -365,12 +366,12 @@ func (ds *dockerService) DockerContainerCopyCreate(info *types.ContainerJSON) (c return container.ID, err } -//param imageName 镜像名称 -//param containerDbId 数据库的id -//param port 容器内部主端口 -//param mapPort 容器主端口映射到外部的端口 -//param tcp 容器其他tcp端口 -//param udp 容器其他udp端口 +// param imageName 镜像名称 +// param containerDbId 数据库的id +// param port 容器内部主端口 +// param mapPort 容器主端口映射到外部的端口 +// param tcp 容器其他tcp端口 +// param udp 容器其他udp端口 func (ds *dockerService) DockerContainerCreate(m model.CustomizationPostData, id string) (containerId string, err error) { if len(m.NetworkModel) == 0 { m.NetworkModel = "bridge" @@ -581,7 +582,7 @@ func (ds *dockerService) DockerContainerCreate(m model.CustomizationPostData, id return containerDb.ID, err } -//删除容器 +// 删除容器 func (ds *dockerService) DockerContainerRemove(name string, update bool) error { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -605,7 +606,7 @@ func (ds *dockerService) DockerContainerRemove(name string, update bool) error { return err } -//删除镜像 +// 删除镜像 func (ds *dockerService) DockerImageRemove(name string) error { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -653,7 +654,7 @@ Loop: return err } -//停止镜像 +// 停止镜像 func (ds *dockerService) DockerContainerStop(id string) error { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -664,7 +665,7 @@ func (ds *dockerService) DockerContainerStop(id string) error { return err } -//启动容器 +// 启动容器 func (ds *dockerService) DockerContainerStart(name string) error { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -675,7 +676,7 @@ func (ds *dockerService) DockerContainerStart(name string) error { return err } -//查看日志 +// 查看日志 func (ds *dockerService) DockerContainerLog(name string) (string, error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -714,7 +715,7 @@ func DockerContainerStats1() error { return nil } -//获取容器状态 +// 获取容器状态 func (ds *dockerService) DockerContainerStats(name string) (string, error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -733,7 +734,7 @@ func (ds *dockerService) DockerContainerStats(name string) (string, error) { return string(sts), nil } -//备份容器 +// 备份容器 func (ds *dockerService) DockerContainerCommit(name string) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -778,7 +779,7 @@ func (ds *dockerService) DockerListByImage(image, version string) (*types.Contai return &containers[0], nil } -//获取容器详情 +// 获取容器详情 func (ds *dockerService) DockerContainerInfo(name string) (*types.ContainerJSON, error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) @@ -793,13 +794,13 @@ func (ds *dockerService) DockerContainerInfo(name string) (*types.ContainerJSON, return &d, nil } -//更新容器 -//param shares cpu优先级 -//param containerDbId 数据库的id -//param port 容器内部主端口 -//param mapPort 容器主端口映射到外部的端口 -//param tcp 容器其他tcp端口 -//param udp 容器其他udp端口 +// 更新容器 +// param shares cpu优先级 +// param containerDbId 数据库的id +// param port 容器内部主端口 +// param mapPort 容器主端口映射到外部的端口 +// param tcp 容器其他tcp端口 +// param udp 容器其他udp端口 func (ds *dockerService) DockerContainerUpdate(m model.CustomizationPostData, id string) (err error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -834,9 +835,9 @@ func (ds *dockerService) DockerContainerUpdate(m model.CustomizationPostData, id return } -//更新容器名称 -//param name 容器名称 -//param id 老的容器名称 +// 更新容器名称 +// param name 容器名称 +// param id 老的容器名称 func (ds *dockerService) DockerContainerUpdateName(name, id string) (err error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { @@ -851,7 +852,7 @@ func (ds *dockerService) DockerContainerUpdateName(name, id string) (err error) return } -//获取网络列表 +// 获取网络列表 func (ds *dockerService) DockerNetworkModelList() []types.NetworkResource { cli, _ := client2.NewClientWithOpts(client2.FromEnv) @@ -863,6 +864,17 @@ func NewDockerService() DockerService { return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`)} } +func (ds *dockerService) GetDockerInfo() (types.Info, error) { + cli, err := client2.NewClientWithOpts(client2.FromEnv) + if err != nil { + return types.Info{}, err + } + defer cli.Close() + + return cli.Info(context.Background()) + +} + // ---------------------------------------test------------------------------------ //func ServiceCreate() { // cli, err := client2.NewClientWithOpts(client2.FromEnv) diff --git a/service/model/o_disk.go b/service/model/o_disk.go deleted file mode 100644 index 1121e87b3..000000000 --- a/service/model/o_disk.go +++ /dev/null @@ -1,25 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.org - * @Date: 2021-12-07 17:14:41 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-08-17 18:46:43 - * @FilePath: /CasaOS/service/model/o_disk.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package model - -//SerialAdvanced Technology Attachment (STAT) -type SerialDisk struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - UUID string `json:"uuid"` - Path string `json:"path"` - State int `json:"state"` - MountPoint string `json:"mount_point"` - CreatedAt int64 `json:"created_at"` -} - -func (p *SerialDisk) TableName() string { - return "o_disk" -} diff --git a/service/notify.go b/service/notify.go index fe93d83af..05d31622c 100644 --- a/service/notify.go +++ b/service/notify.go @@ -31,11 +31,9 @@ type NotifyServer interface { SendNetInfoBySocket(netList []model2.IOCountersStat) SendCPUInfoBySocket(cpu map[string]interface{}) SendMemInfoBySocket(mem map[string]interface{}) - SendUSBInfoBySocket(list []model2.DriveUSB) - SendDiskInfoBySocket(disk model2.Summary) SendFileOperateNotify(nowSend bool) SendInstallAppBySocket(app notify.Application) - SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) + SendAllHardwareStatusBySocket(mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) SendStorageBySocket(message notify.StorageMessage) SendNotify(path string, message map[string]interface{}) SettingSystemTempData(message map[string]interface{}) @@ -81,7 +79,7 @@ func (i *notifyServer) SendStorageBySocket(message notify.StorageMessage) { NotifyMsg <- notify } -func (i *notifyServer) SendAllHardwareStatusBySocket(disk model2.Summary, list []model2.DriveUSB, mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) { +func (i *notifyServer) SendAllHardwareStatusBySocket(mem map[string]interface{}, cpu map[string]interface{}, netList []model2.IOCountersStat) { body := make(map[string]interface{}) @@ -263,38 +261,6 @@ func (i *notifyServer) SendFileOperateNotify(nowSend bool) { } -func (i *notifyServer) SendDiskInfoBySocket(disk model2.Summary) { - body := make(map[string]interface{}) - body["data"] = disk - - msg := gosf.Message{} - msg.Body = body - msg.Success = true - msg.Text = "sys_disk" - - notify := notify.Message{} - notify.Path = "sys_disk" - notify.Msg = msg - - NotifyMsg <- notify -} - -func (i *notifyServer) SendUSBInfoBySocket(list []model2.DriveUSB) { - body := make(map[string]interface{}) - body["data"] = list - - msg := gosf.Message{} - msg.Body = body - msg.Success = true - msg.Text = "sys_usb" - - notify := notify.Message{} - notify.Path = "sys_usb" - notify.Msg = msg - - NotifyMsg <- notify -} - func (i *notifyServer) SendMemInfoBySocket(mem map[string]interface{}) { body := make(map[string]interface{}) body["data"] = mem diff --git a/service/service.go b/service/service.go index 16594b97b..e2164c099 100644 --- a/service/service.go +++ b/service/service.go @@ -30,7 +30,6 @@ type Repository interface { //User() UserService Docker() DockerService Casa() CasaService - Disk() DiskService Notify() NotifyServer Rely() RelyService System() SystemService @@ -51,7 +50,6 @@ func NewService(db *gorm.DB, RuntimePath string) Repository { app: NewAppService(db), docker: NewDockerService(), casa: NewCasaService(), - disk: NewDiskService(db), notify: NewNotifyService(db), rely: NewRelyService(db), system: NewSystemService(), @@ -65,7 +63,6 @@ type store struct { app AppService docker DockerService casa CasaService - disk DiskService notify NotifyServer rely RelyService system SystemService @@ -107,7 +104,3 @@ func (c *store) Docker() DockerService { func (c *store) Casa() CasaService { return c.casa } - -func (c *store) Disk() DiskService { - return c.disk -} From 80c347ac018610d207659f46ccb15f587c104c6e Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Fri, 16 Sep 2022 04:47:42 +0100 Subject: [PATCH 09/21] update http status --- common/notify.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/notify.go b/common/notify.go index 82d339407..a5cee48b6 100644 --- a/common/notify.go +++ b/common/notify.go @@ -36,7 +36,7 @@ func (n *notifyService) SendNotify(path string, message map[string]interface{}) return err } - if response.StatusCode != http.StatusCreated { + if response.StatusCode != http.StatusOK { return errors.New("failed to send notify (status code: " + fmt.Sprint(response.StatusCode) + ")") } return nil @@ -58,7 +58,7 @@ func (n *notifyService) SendSystemStatusNotify(message map[string]interface{}) e return err } - if response.StatusCode != http.StatusCreated { + if response.StatusCode != http.StatusOK { return errors.New("failed to send notify (status code: " + fmt.Sprint(response.StatusCode) + ")") } return nil From aff18fa091f5368c35db9e2880433696324d8ecf Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Mon, 19 Sep 2022 10:09:04 +0100 Subject: [PATCH 10/21] add share function to common --- common/share.go | 78 ++++++++++++++++++++++++++++++++++++++++++++ common/share_test.go | 14 ++++++++ 2 files changed, 92 insertions(+) create mode 100644 common/share.go create mode 100644 common/share_test.go diff --git a/common/share.go b/common/share.go new file mode 100644 index 000000000..a0da4b2d0 --- /dev/null +++ b/common/share.go @@ -0,0 +1,78 @@ +package common + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "path/filepath" + "strings" +) + +const ( + APICasaOSShare = "/v1/samba/shares" +) + +type ShareService interface { + DeleteShare(id string) error +} +type shareService struct { + address string +} + +func (n *shareService) DeleteShare(id string) error { + url := strings.TrimSuffix(n.address, "/") + APICasaOSShare + "/" + id + fmt.Println(url) + message := "{}" + body, err := json.Marshal(message) + if err != nil { + return err + } + + client := &http.Client{} + + // Create request + req, err := http.NewRequest("DELETE", url, bytes.NewBuffer(body)) + if err != nil { + return err + } + + // Fetch Request + response, err := client.Do(req) + if err != nil { + return err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return errors.New("failed to send share (status code: " + fmt.Sprint(response.StatusCode) + ")") + } + return nil + +} + +func NewShareService(runtimePath string) (ShareService, error) { + casaosAddressFile := filepath.Join(runtimePath, CasaOSURLFilename) + + buf, err := os.ReadFile(casaosAddressFile) + if err != nil { + return nil, err + } + + address := string(buf) + + response, err := http.Get(address + "/ping") + if err != nil { + return nil, err + } + + if response.StatusCode != 200 { + return nil, errors.New("failed to ping casaos service") + } + + return &shareService{ + address: address, + }, nil +} diff --git a/common/share_test.go b/common/share_test.go new file mode 100644 index 000000000..ce79e032d --- /dev/null +++ b/common/share_test.go @@ -0,0 +1,14 @@ +package common + +import "testing" + +func TestDeleteShare(t *testing.T) { + share, err := NewShareService("/var/run/casaos") + if err != nil { + t.Fatal(err) + } + err = share.DeleteShare("1") + if err != nil { + t.Fatal(err) + } +} From f0448cd1b939e488b092fe73d784bb823b3382fb Mon Sep 17 00:00:00 2001 From: LinkLeong Date: Wed, 28 Sep 2022 16:13:42 +0100 Subject: [PATCH 11/21] remove temp path --- .gitignore | 3 ++- .../migration/script.d/03-migrate-casaos.sh | 7 ++++--- build/sysroot/etc/casaos/casaos.conf.sample | 1 - conf/conf.conf.sample | 1 - model/sys_common.go | 11 +++++------ pkg/config/init.go | 13 +++++-------- route/v1/docker.go | 2 +- route/v1/file.go | 8 +++++--- service/casa.go | 8 -------- service/docker.go | 17 ++++++++++------- 10 files changed, 32 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 51d11d0a2..411aba356 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ __debug_bin main github.com .all-contributorsrc -dist \ No newline at end of file +dist +CasaOS \ No newline at end of file diff --git a/build/scripts/migration/script.d/03-migrate-casaos.sh b/build/scripts/migration/script.d/03-migrate-casaos.sh index ba64e4df0..a48c43765 100644 --- a/build/scripts/migration/script.d/03-migrate-casaos.sh +++ b/build/scripts/migration/script.d/03-migrate-casaos.sh @@ -60,8 +60,8 @@ BUILD_PATH=$(dirname "${BASH_SOURCE[0]}")/../../.. SOURCE_ROOT=${BUILD_PATH}/sysroot APP_NAME="casaos" -# APP_NAME_FORMAL="CasaOS" -APP_NAME_FORMAL="casaos-alpha" +APP_NAME_FORMAL="CasaOS" +#APP_NAME_FORMAL="casaos-alpha" # check if migration is needed SOURCE_BIN_PATH=${SOURCE_ROOT}/usr/bin @@ -153,7 +153,8 @@ pushd "${MIGRATION_SERVICE_DIR}" continue fi - MIGRATION_TOOL_URL=https://github.com/LinkLeong/"${APP_NAME_FORMAL}"/releases/download/"${VER2}"/linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz + # MIGRATION_TOOL_URL=http://192.168.2.197:8000/v1/package/migration?type=release&name="${APP_NAME_FORMAL}"&version=${VER2}&arch=${ARCH} + MIGRATION_TOOL_URL=https://github.com/IceWhaleTech/"${APP_NAME_FORMAL}"/releases/download/"${VER2}"/linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz echo "Dowloading ${MIGRATION_TOOL_URL}..." curl -sL -O "${MIGRATION_TOOL_URL}" done diff --git a/build/sysroot/etc/casaos/casaos.conf.sample b/build/sysroot/etc/casaos/casaos.conf.sample index 3e6450858..e51f0fa48 100644 --- a/build/sysroot/etc/casaos/casaos.conf.sample +++ b/build/sysroot/etc/casaos/casaos.conf.sample @@ -11,7 +11,6 @@ DateFormat = 2006-01-02 DBPath = /var/lib/casaos ShellPath = /usr/share/casaos/shell UserDataPath = /var/lib/casaos/conf -TempPath = /var/lib/casaos/temp [server] RunMode = release diff --git a/conf/conf.conf.sample b/conf/conf.conf.sample index 5ce1d0eaf..136441863 100644 --- a/conf/conf.conf.sample +++ b/conf/conf.conf.sample @@ -11,7 +11,6 @@ DateFormat = 2006-01-02 DBPath = /var/lib/casaos ShellPath = /usr/share/casaos/shell UserDataPath = /var/lib/casaos/conf -TempPath = /var/lib/casaos/temp [server] RunMode = release diff --git a/model/sys_common.go b/model/sys_common.go index 1a788676d..73316b0d8 100644 --- a/model/sys_common.go +++ b/model/sys_common.go @@ -12,12 +12,12 @@ package model import "time" -//系统配置 +// 系统配置 type SysInfoModel struct { Name string //系统名称 } -//服务配置 +// 服务配置 type ServerModel struct { HttpPort string RunMode string @@ -28,7 +28,7 @@ type ServerModel struct { SocketPort string } -//服务配置 +// 服务配置 type APPModel struct { LogPath string LogSaveName string @@ -40,20 +40,19 @@ type APPModel struct { DateFormat string DBPath string ShellPath string - TempPath string } type CommonModel struct { RuntimePath string } -//公共返回模型 +// 公共返回模型 type Result struct { Success int `json:"success" example:"200"` Message string `json:"message" example:"ok"` Data interface{} `json:"data" example:"返回结果"` } -//redis配置文件 +// redis配置文件 type RedisModel struct { Host string Password string diff --git a/pkg/config/init.go b/pkg/config/init.go index c79d71f44..b2de00f91 100644 --- a/pkg/config/init.go +++ b/pkg/config/init.go @@ -23,17 +23,17 @@ import ( "github.com/go-ini/ini" ) -//系统配置 +// 系统配置 var SysInfo = &model.SysInfoModel{} -//用户相关 +// 用户相关 var AppInfo = &model.APPModel{} var CommonInfo = &model.CommonModel{} //var RedisInfo = &model.RedisModel{} -//server相关 +// server相关 var ServerInfo = &model.ServerModel{} var SystemConfigInfo = &model.SystemConfig{} @@ -44,7 +44,7 @@ var FileSettingInfo = &model.FileSetting{} var Cfg *ini.File -//初始化设置,获取系统的部分信息。 +// 初始化设置,获取系统的部分信息。 func InitSetup(config string) { var configDir = USERCONFIGURL @@ -86,9 +86,6 @@ func InitSetup(config string) { if len(AppInfo.UserDataPath) == 0 { AppInfo.UserDataPath = "/var/lib/casaos/conf" } - if len(AppInfo.TempPath) == 0 { - AppInfo.TempPath = "/var/lib/casaos/temp" - } if len(CommonInfo.RuntimePath) == 0 { CommonInfo.RuntimePath = "/var/run/casaos" } @@ -97,7 +94,7 @@ func InitSetup(config string) { } -//映射 +// 映射 func mapTo(section string, v interface{}) { err := Cfg.Section(section).MapTo(v) if err != nil { diff --git a/route/v1/docker.go b/route/v1/docker.go index 8c1254f42..4b7d4a4a3 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -761,7 +761,7 @@ func ChangAppState(c *gin.Context) { func ContainerLog(c *gin.Context) { appId := c.Param("id") log, _ := service.MyService.Docker().DockerContainerLog(appId) - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: log}) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(log)}) } // @Summary 获取容器状态 diff --git a/route/v1/file.go b/route/v1/file.go index 548ee4a0b..396074d8e 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -16,7 +16,6 @@ import ( "sync" "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/service" @@ -267,6 +266,9 @@ func DirPath(c *gin.Context) { pathList := []model.Path{} for i := 0; i < len(info); i++ { + if info[i].Name == ".temp" && info[i].IsDir { + continue + } if _, ok := fileQueue[info[i].Path]; !ok { pathList = append(pathList, info[i]) } @@ -367,7 +369,7 @@ func GetFileUpload(c *gin.Context) { path := c.Query("path") dirPath := "" hash := file.GetHashByContent([]byte(fileName)) - tempDir := config.AppInfo.TempPath + "/" + hash + strconv.Itoa(totalChunks) + "/" + tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/" if fileName != relative { dirPath = strings.TrimSuffix(relative, fileName) tempDir += dirPath @@ -406,7 +408,7 @@ func PostFileUpload(c *gin.Context) { c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - tempDir := config.AppInfo.TempPath + "/" + hash + strconv.Itoa(totalChunks) + "/" + tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/" if fileName != relative { dirPath = strings.TrimSuffix(relative, fileName) diff --git a/service/casa.go b/service/casa.go index f5a71d39e..4d80bf480 100644 --- a/service/casa.go +++ b/service/casa.go @@ -130,10 +130,6 @@ func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollec errr := json2.Unmarshal(results, &collection) if errr != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) - } else { - if collection.Version == o.GetCasaosVersion().Version { - return collection, err - } } head := make(map[string]string) @@ -204,10 +200,6 @@ func (o *casaService) AsyncGetServerCategoryList() ([]model.CategoryList, error) err := json2.Unmarshal(results, &list) if err != nil { loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) - } else { - if list.Version == o.GetCasaosVersion().Version { - return list.Item, nil - } } item := []model.CategoryList{} head := make(map[string]string) diff --git a/service/docker.go b/service/docker.go index 812fb8a39..f453c0b6d 100644 --- a/service/docker.go +++ b/service/docker.go @@ -52,7 +52,7 @@ type DockerService interface { DockerContainerStop(id string) error DockerContainerUpdateName(name, id string) (err error) DockerContainerUpdate(m model.CustomizationPostData, id string) (err error) - DockerContainerLog(name string) (string, error) + DockerContainerLog(name string) ([]byte, error) DockerContainerCommit(name string) DockerContainerList() []types.Container DockerNetworkModelList() []types.NetworkResource @@ -677,23 +677,26 @@ func (ds *dockerService) DockerContainerStart(name string) error { } // 查看日志 -func (ds *dockerService) DockerContainerLog(name string) (string, error) { +func (ds *dockerService) DockerContainerLog(name string) ([]byte, error) { cli, err := client2.NewClientWithOpts(client2.FromEnv) if err != nil { - return "", err + return []byte(""), err } defer cli.Close() - body, err := cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true}) + //body, err := cli.ContainerAttach(context.Background(), name, types.ContainerAttachOptions{Logs: true, Stream: false, Stdin: false, Stdout: false, Stderr: false}) + body, err := cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true}) + if err != nil { - return "", err + return []byte(""), err } defer body.Close() content, err := ioutil.ReadAll(body) + //content, err := ioutil.ReadAll(body) if err != nil { - return "", err + return []byte(""), err } - return string(content), nil + return content, nil } func DockerContainerStats1() error { From 455d226dcdb3f59595e5a705fa24ecfb75d60bf6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 28 Sep 2022 11:14:19 -0400 Subject: [PATCH 12/21] remove /DATA directory initialization - moved to local-storage (#578) --- cmd/migration-tool/main.go | 18 +++++++++++------- main.go | 30 +++++++++++++++--------------- pkg/config/update.go | 32 -------------------------------- 3 files changed, 26 insertions(+), 54 deletions(-) delete mode 100644 pkg/config/update.go diff --git a/cmd/migration-tool/main.go b/cmd/migration-tool/main.go index 5f7c60b59..93b065d3e 100644 --- a/cmd/migration-tool/main.go +++ b/cmd/migration-tool/main.go @@ -28,25 +28,29 @@ const ( casaosServiceName = "casaos.service" ) -var _logger *Logger -var sqliteDB *gorm.DB +var ( + _logger *Logger + sqliteDB *gorm.DB +) -var configFlag = "" -var dbFlag = "" +var ( + configFlag = "" + dbFlag = "" +) func init() { config.InitSetup(configFlag) - config.UpdateSetup() if len(dbFlag) == 0 { dbFlag = config.AppInfo.DBPath + "/db" } sqliteDB = sqlite.GetDb(dbFlag) - //gredis.GetRedisConn(config.RedisInfo), + // gredis.GetRedisConn(config.RedisInfo), service.MyService = service.NewService(sqliteDB, "") } + func main() { versionFlag := flag.Bool("v", false, "version") debugFlag := flag.Bool("d", true, "debug") @@ -113,6 +117,6 @@ func main() { selectedMigrationTool.PostMigrate() _logger.Info("casaos migration ok") - //panic(err) + // panic(err) } diff --git a/main.go b/main.go index f02afcab8..32b1c018f 100644 --- a/main.go +++ b/main.go @@ -28,9 +28,11 @@ const LOCALHOST = "127.0.0.1" var sqliteDB *gorm.DB -var configFlag = flag.String("c", "", "config address") -var dbFlag = flag.String("db", "", "db path") -var versionFlag = flag.Bool("v", false, "version") +var ( + configFlag = flag.String("c", "", "config address") + dbFlag = flag.String("db", "", "db path") + versionFlag = flag.Bool("v", false, "version") +) func init() { flag.Parse() @@ -39,7 +41,6 @@ func init() { return } config.InitSetup(*configFlag) - config.UpdateSetup() loger.LogInit() if len(*dbFlag) == 0 { @@ -47,7 +48,7 @@ func init() { } sqliteDB = sqlite.GetDb(*dbFlag) - //gredis.GetRedisConn(config.RedisInfo), + // gredis.GetRedisConn(config.RedisInfo), service.MyService = service.NewService(sqliteDB, config.CommonInfo.RuntimePath) @@ -60,7 +61,6 @@ func init() { // go service.LoopFriend() // go service.MyService.App().CheckNewImage() - } // @title casaOS API @@ -80,21 +80,21 @@ func main() { return } go route.SocketInit(service.NotifyMsg) - //model.Setup() - //gredis.Setup() + // model.Setup() + // gredis.Setup() r := route.InitRouter() - //service.SyncTask(sqliteDB) + // service.SyncTask(sqliteDB) cron2 := cron.New() - //every day execution + // every day execution err := cron2.AddFunc("0/5 * * * * *", func() { if service.ClientCount > 0 { - //route.SendNetINfoBySocket() - //route.SendCPUBySocket() - //route.SendMemBySocket() + // route.SendNetINfoBySocket() + // route.SendCPUBySocket() + // route.SendMemBySocket() // route.SendDiskBySocket() - //route.SendUSBBySocket() + // route.SendUSBBySocket() route.SendAllHardwareStatusBySocket() } }) @@ -123,7 +123,7 @@ func main() { } go func() { time.Sleep(time.Second * 2) - //v0.3.6 + // v0.3.6 if config.ServerInfo.HttpPort != "" { changePort := common.ChangePortRequest{} changePort.Port = config.ServerInfo.HttpPort diff --git a/pkg/config/update.go b/pkg/config/update.go deleted file mode 100644 index 7dbae8247..000000000 --- a/pkg/config/update.go +++ /dev/null @@ -1,32 +0,0 @@ -package config - -import ( - "runtime" - - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" -) - -//检查目录是否存在 -func mkdirDATAAll() { - sysType := runtime.GOOS - var dirArray []string - if sysType == "linux" { - dirArray = []string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"} - } - - if sysType == "windows" { - dirArray = []string{"C:\\CasaOS\\DATA\\AppData", "C:\\CasaOS\\DATA\\Documents", "C:\\CasaOS\\DATA\\Downloads", "C:\\CasaOS\\DATA\\Gallery", "C:\\CasaOS\\DATA\\Media/Movies", "C:\\CasaOS\\DATA\\Media\\TV Shows", "C:\\CasaOS\\DATA\\Media\\Music"} - } - if sysType == "darwin" { - dirArray = []string{"./CasaOS/DATA/AppData", "./CasaOS/DATA/Documents", "./CasaOS/DATA/Downloads", "./CasaOS/DATA/Gallery", "./CasaOS/DATA/Media/Movies", "./CasaOS/DATA/Media/TV Shows", "./CasaOS/DATA/Media/Music"} - } - - for _, v := range dirArray { - file.IsNotExistMkDir(v) - } - -} - -func UpdateSetup() { - mkdirDATAAll() -} From 12d5e5db03687c343cd41cc74193db5d2338ef1f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 28 Sep 2022 12:21:44 -0400 Subject: [PATCH 13/21] update goreleaser configuration --- .goreleaser.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 949e04f84..690519ddb 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -117,7 +117,7 @@ builds: goarch: - arm goarm: - - "7" + - "7" archives: - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}" id: casaos @@ -159,9 +159,9 @@ changelog: # name_template: "v{{ .Version }}" release: github: - owner: LinkLeong - name: casaos-alpha + owner: IceWhaleTech + name: CasaOS draft: true prerelease: auto mode: replace - name_template: "v{{ .Version }}" \ No newline at end of file + name_template: "v{{ .Version }}" From 182bc25343c99acb89f7729acdcfdb8cbf532f78 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 28 Sep 2022 17:56:28 -0400 Subject: [PATCH 14/21] wip --- .../usr/lib/systemd/system/casaos.service | 3 ++- go.mod | 1 + main.go | 24 ++++++++++++------- types/system.go | 19 +++++++-------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/build/sysroot/usr/lib/systemd/system/casaos.service b/build/sysroot/usr/lib/systemd/system/casaos.service index 249d72c9b..aa7ad32e8 100644 --- a/build/sysroot/usr/lib/systemd/system/casaos.service +++ b/build/sysroot/usr/lib/systemd/system/casaos.service @@ -1,12 +1,13 @@ [Unit] After=casaos-gateway.service ConditionFileNotEmpty=/etc/casaos/casaos.conf -Description=CasaOS Service +Description=CasaOS Main Service [Service] ExecStart=/usr/bin/casaos -c /etc/casaos/casaos.conf PIDFile=/var/run/casaos/casaos.pid Restart=always +Type=notify [Install] WantedBy=multi-user.target diff --git a/go.mod b/go.mod index cfcc59bba..db9ca62fe 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109 github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 // indirect github.com/containerd/containerd v1.5.7 // indirect + github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e github.com/disintegration/imaging v1.6.2 github.com/docker/distribution v2.8.0+incompatible // indirect github.com/docker/docker v20.10.7+incompatible diff --git a/main.go b/main.go index 32b1c018f..ede006dec 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "github.com/IceWhaleTech/CasaOS/route" "github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/types" + "github.com/coreos/go-systemd/daemon" "go.uber.org/zap" "github.com/robfig/cron" @@ -135,14 +136,6 @@ func main() { } }() - // s := &http.Server{ - // Addr: listener.Addr().String(), //fmt.Sprintf(":%v", config.ServerInfo.HttpPort), - // Handler: r, - // ReadTimeout: 60 * time.Second, - // WriteTimeout: 60 * time.Second, - // MaxHeaderBytes: 1 << 20, - // } - // s.ListenAndServe() urlFilePath := filepath.Join(config.CommonInfo.RuntimePath, "casaos.url") err = file.CreateFileAndWriteContent(urlFilePath, "http://"+listener.Addr().String()) if err != nil { @@ -152,7 +145,20 @@ func main() { ) } - err = http.Serve(listener, r) + if supported, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil { + loger.Error("Failed to notify systemd that casaos main service is ready", zap.Any("error", err)) + } else if supported { + loger.Info("Notified systemd that casaos main service is ready") + } else { + loger.Info("This process is not running as a systemd service.") + } + + s := &http.Server{ + Handler: r, + ReadHeaderTimeout: 5 * time.Second, // fix G112: Potential slowloris attack (see https://github.com/securego/gosec) + } + + err = s.Serve(listener) // not using http.serve() to fix G114: Use of net/http serve function that has no support for setting timeouts (see https://github.com/securego/gosec) if err != nil { panic(err) } diff --git a/types/system.go b/types/system.go index 24ef182f1..e77a7d6df 100644 --- a/types/system.go +++ b/types/system.go @@ -1,15 +1,14 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-02-17 18:53:22 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-09-06 14:27:42 - * @FilePath: /CasaOS/types/system.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. +/*@Author: LinkLeong link@icewhale.com + *@Date: 2022-02-17 18:53:22 + *@LastEditors: LinkLeong + *@LastEditTime: 2022-09-06 14:27:42 + *@FilePath: /CasaOS/types/system.go + *@Description: + *@Website: https://www.casaos.io + *Copyright (c) 2022 by icewhale, All Rights Reserved. */ package types -const CURRENTVERSION = "0.3.6" +const CURRENTVERSION = "0.3.7" const BODY = " " From b41d855f73a8444bbf44b8e9c81ab2319d44872d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 28 Sep 2022 18:19:31 -0400 Subject: [PATCH 15/21] change service type to notify for systemd so its status is OK only when service is initialized successfully --- build/scripts/setup/service.d/casaos/debian/setup-casaos.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh b/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh index a13b6e1e1..e083373c8 100644 --- a/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh +++ b/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh @@ -40,6 +40,6 @@ else echo "Enabling service..." systemctl enable --force --no-ask-password "${APP_NAME}.service" - echo "Starting service..." - systemctl start --force --no-ask-password "${APP_NAME}.service" + #echo "Starting service..." + #systemctl start --force --no-ask-password "${APP_NAME}.service" fi \ No newline at end of file From 2eac0408754ab340edc67272c3e67a5ff332dadc Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 Sep 2022 00:05:12 -0400 Subject: [PATCH 16/21] update CasaOS-Common to fix runtime error --- .goreleaser.debug.yaml | 167 +++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- middleware/gin.go | 12 +-- 4 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 .goreleaser.debug.yaml diff --git a/.goreleaser.debug.yaml b/.goreleaser.debug.yaml new file mode 100644 index 000000000..885e3a047 --- /dev/null +++ b/.goreleaser.debug.yaml @@ -0,0 +1,167 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com +project_name: casaos +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy +builds: + - id: casaos-amd64 + binary: build/sysroot/usr/bin/casaos + env: + - CGO_ENABLED=1 + - CC=x86_64-linux-gnu-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - amd64 + hooks: + post: + - find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest + - id: casaos-arm64 + binary: build/sysroot/usr/bin/casaos + env: + - CGO_ENABLED=1 + - CC=aarch64-linux-gnu-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - arm64 + hooks: + post: + - find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest + - id: casaos-arm-7 + binary: build/sysroot/usr/bin/casaos + env: + - CGO_ENABLED=1 + - CC=arm-linux-gnueabihf-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - arm + goarm: + - "7" + hooks: + post: + - find build/sysroot -type f | xargs -L 1 realpath --relative-to=build/sysroot > build/sysroot.manifest + - id: casaos-migration-tool-amd64 + binary: build/sysroot/usr/bin/casaos-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=x86_64-linux-gnu-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - amd64 + - id: casaos-migration-tool-arm64 + binary: build/sysroot/usr/bin/casaos-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=aarch64-linux-gnu-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - arm64 + - id: casaos-migration-tool-arm-7 + binary: build/sysroot/usr/bin/casaos-migration-tool + main: ./cmd/migration-tool + env: + - CGO_ENABLED=1 + - CC=arm-linux-gnueabihf-gcc + gcflags: + - all=-N -l + ldflags: + - -extldflags "-static" + tags: + - musl + - netgo + goos: + - linux + goarch: + - arm + goarm: + - "7" +archives: + - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}" + id: casaos + builds: + - casaos-amd64 + - casaos-arm64 + - casaos-arm-7 + replacements: + arm: arm-7 + files: + - build/**/* + - name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}" + id: casaos-migration-tool + builds: + - casaos-migration-tool-amd64 + - casaos-migration-tool-arm64 + - casaos-migration-tool-arm-7 + replacements: + arm: arm-7 + files: + - build/sysroot/etc/**/* +checksum: + name_template: "checksums.txt" +snapshot: + name_template: "{{ incpatch .Version }}" +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +# release: +# github: +# owner: IceWhaleTech +# name: CasaOS +# draft: true +# prerelease: auto +# mode: replace +# name_template: "v{{ .Version }}" +release: + github: + owner: IceWhaleTech + name: CasaOS + draft: true + prerelease: auto + mode: replace + name_template: "v{{ .Version }}" diff --git a/go.mod b/go.mod index db9ca62fe..6c454be13 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d - github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5 + github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8 github.com/IceWhaleTech/CasaOS-Gateway v0.3.6 github.com/Microsoft/go-winio v0.5.0 // indirect github.com/ambelovsky/go-structs v1.1.0 // indirect diff --git a/go.sum b/go.sum index 49a1770f2..0bf42e298 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220901034123-ca130f6b5ce9/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= -github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5 h1:vgAf0jVKCBo3wyjOZ4z9tB77lVrgIfz2CcQX2+4JTSI= -github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220909125858-92fc5b2e0ae5/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8 h1:r8nhgQ6tnrn6ikXN9aLH/K4H4H64Nc0hZ6jyW2B22x0= +github.com/IceWhaleTech/CasaOS-Common v0.0.0-20220929035515-b1287110d6d8/go.mod h1:2MiivEMzvh41codhEKUcn46WK3Ffesop/04qa9jsvQk= github.com/IceWhaleTech/CasaOS-Gateway v0.3.6 h1:2tQQo85+jzbbjqIsKKn77QlAA73bc7vZsVCFvWnK4mg= github.com/IceWhaleTech/CasaOS-Gateway v0.3.6/go.mod h1:hnZwGUzcOyiufMpVO7l3gu2gAm6Ws4TY4Nlj3kMshXA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= diff --git a/middleware/gin.go b/middleware/gin.go index d8fd836dc..a9b07b680 100644 --- a/middleware/gin.go +++ b/middleware/gin.go @@ -13,6 +13,7 @@ package middleware import ( "fmt" "net/http" + "runtime/debug" "strings" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" @@ -26,18 +27,18 @@ func Cors() gin.HandlerFunc { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") - //允许跨域设置可以返回其他子段,可以自定义字段 + // 允许跨域设置可以返回其他子段,可以自定义字段 c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language,Content-Type,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Connection,Host,Origin,Referer,User-Agent,X-Requested-With") // 允许浏览器(客户端)可以解析的头部 (重要) c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers") - //c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With") - //设置缓存时间 + // c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With") + // 设置缓存时间 c.Header("Access-Control-Max-Age", "172800") c.Header("Access-Control-Allow-Credentials", "true") c.Set("Content-Type", "application/json") //} - //允许类型校验 + // 允许类型校验 if method == "OPTIONS" { c.JSON(http.StatusOK, "ok!") } @@ -45,18 +46,19 @@ func Cors() gin.HandlerFunc { defer func() { if err := recover(); err != nil { fmt.Println(err) + debug.PrintStack() } }() c.Next() } } + func WriteLog() gin.HandlerFunc { return func(c *gin.Context) { if !strings.Contains(c.Request.URL.String(), "password") { loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("method", c.Request.Method)) c.Next() } - } } From ff6cdb6fda57f0d4ebbacd7b625459f0950b5117 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 11 Oct 2022 00:19:02 -0400 Subject: [PATCH 17/21] wip --- model/docker.go | 6 +- pkg/docker/helper.go | 72 ++++++++++----------- pkg/utils/command/command_helper.go | 13 ++-- pkg/utils/file/file.go | 39 +++++++----- route/route.go | 63 +++++++++--------- route/v1/app.go | 99 ++++++++++++++++++++--------- 6 files changed, 170 insertions(+), 122 deletions(-) diff --git a/model/docker.go b/model/docker.go index 20b68cc5c..34412cdc3 100644 --- a/model/docker.go +++ b/model/docker.go @@ -17,6 +17,8 @@ type DockerStatsModel struct { Previous interface{} `json:"previous"` } -type DeckerDaemonModel struct { - Graph string `json:"graph"` +// reference - https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file +type DockerDaemonConfigurationModel struct { + // e.g. `/var/lib/docker` + Root string `json:"data-root,omitempty"` } diff --git a/pkg/docker/helper.go b/pkg/docker/helper.go index be76b7d5c..0aef1178b 100644 --- a/pkg/docker/helper.go +++ b/pkg/docker/helper.go @@ -15,7 +15,6 @@ import ( ) func NewSshClient(user, password string, port string) (*ssh.Client, error) { - // connet to ssh // addr = fmt.Sprintf("%s:%d", host, port) @@ -23,10 +22,10 @@ func NewSshClient(user, password string, port string) (*ssh.Client, error) { Timeout: time.Second * 5, User: user, HostKeyCallback: ssh.InsecureIgnoreHostKey(), - //HostKeyCallback: , - //HostKeyCallback: hostKeyCallBackFunc(h.Host), + // HostKeyCallback: , + // HostKeyCallback: hostKeyCallBackFunc(h.Host), } - //if h.Type == "password" { + // if h.Type == "password" { config.Auth = []ssh.AuthMethod{ssh.Password(password)} //} else { // config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(h.Key)} @@ -90,11 +89,11 @@ func (w *wsBufferWriter) Write(p []byte) (int, error) { defer w.mu.Unlock() return w.buffer.Write(p) } + func (s *SshConn) Close() { if s.Session != nil { s.Session.Close() } - } const ( @@ -102,16 +101,15 @@ const ( wsMsgResize = "resize" ) -//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin +// ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string { - //tells other go routine quit + // tells other go routine quit username := "" for { - //read websocket msg + // read websocket msg _, wsData, err := wsConn.ReadMessage() if err != nil { - return "" } @@ -125,8 +123,8 @@ func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string { //} switch msgObj.Type { case wsMsgCmd: - //handle xterm.js stdin - //decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) + // handle xterm.js stdin + // decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) decodeBytes := []byte(msgObj.Cmd) if msgObj.Cmd == "\u007f" { if len(username) == 0 { @@ -144,7 +142,7 @@ func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string { if err := wsConn.WriteMessage(websocket.TextMessage, decodeBytes); err != nil { logrus.WithError(err).Error("ws cmd bytes write to ssh.stdin pipe failed") } - //write input cmd to log buffer + // write input cmd to log buffer if _, err := logBuff.Write(decodeBytes); err != nil { logrus.WithError(err).Error("write received cmd into log buffer failed") } @@ -154,11 +152,11 @@ func ReceiveWsMsgUser(wsConn *websocket.Conn, logBuff *bytes.Buffer) string { } func ReceiveWsMsgPassword(wsConn *websocket.Conn, logBuff *bytes.Buffer) string { - //tells other go routine quit + // tells other go routine quit password := "" for { - //read websocket msg + // read websocket msg _, wsData, err := wsConn.ReadMessage() if err != nil { logrus.WithError(err).Error("reading webSocket message failed") @@ -175,8 +173,8 @@ func ReceiveWsMsgPassword(wsConn *websocket.Conn, logBuff *bytes.Buffer) string //} switch msgObj.Type { case wsMsgCmd: - //handle xterm.js stdin - //decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) + // handle xterm.js stdin + // decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) if msgObj.Cmd == "\r" { return password } @@ -194,16 +192,16 @@ func ReceiveWsMsgPassword(wsConn *websocket.Conn, logBuff *bytes.Buffer) string } } -//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin +// ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffer, exitCh chan bool) { - //tells other go routine quit + // tells other go routine quit defer setQuit(exitCh) for { select { case <-exitCh: return default: - //read websocket msg + // read websocket msg _, wsData, err := wsConn.ReadMessage() if err != nil { logrus.WithError(err).Error("reading webSocket message failed") @@ -227,15 +225,15 @@ func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffe switch msgObj.Type { case wsMsgResize: - //handle xterm.js size change + // handle xterm.js size change if msgObj.Cols > 0 && msgObj.Rows > 0 { if err := ssConn.Session.WindowChange(msgObj.Rows, msgObj.Cols); err != nil { logrus.WithError(err).Error("ssh pty change windows size failed") } } case wsMsgCmd: - //handle xterm.js stdin - //decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) + // handle xterm.js stdin + // decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) decodeBytes := []byte(msgObj.Cmd) if err != nil { logrus.WithError(err).Error("websock cmd string base64 decoding failed") @@ -243,7 +241,7 @@ func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffe if _, err := ssConn.StdinPipe.Write(decodeBytes); err != nil { logrus.WithError(err).Error("ws cmd bytes write to ssh.stdin pipe failed") } - //write input cmd to log buffer + // write input cmd to log buffer if _, err := logBuff.Write(decodeBytes); err != nil { logrus.WithError(err).Error("write received cmd into log buffer failed") } @@ -253,17 +251,17 @@ func (ssConn *SshConn) ReceiveWsMsg(wsConn *websocket.Conn, logBuff *bytes.Buffe } func (ssConn *SshConn) SendComboOutput(wsConn *websocket.Conn, exitCh chan bool) { - //tells other go routine quit - //defer setQuit(exitCh) + // tells other go routine quit + // defer setQuit(exitCh) - //every 120ms write combine output bytes into websocket response + // every 120ms write combine output bytes into websocket response tick := time.NewTicker(time.Millisecond * time.Duration(120)) - //for range time.Tick(120 * time.Millisecond){} + // for range time.Tick(120 * time.Millisecond){} defer tick.Stop() for { select { case <-tick.C: - //write combine output bytes into websocket response + // write combine output bytes into websocket response if err := flushComboOutput(ssConn.ComboOutput, wsConn); err != nil { logrus.WithError(err).Error("ssh sending combo output to webSocket failed") return @@ -273,6 +271,7 @@ func (ssConn *SshConn) SendComboOutput(wsConn *websocket.Conn, exitCh chan bool) } } } + func flushComboOutput(w *wsBufferWriter, wsConn *websocket.Conn) error { if w.buffer.Len() != 0 { err := wsConn.WriteMessage(websocket.TextMessage, w.buffer.Bytes()) @@ -284,16 +283,16 @@ func flushComboOutput(w *wsBufferWriter, wsConn *websocket.Conn) error { return nil } -//ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin +// ReceiveWsMsg receive websocket msg do some handling then write into ssh.session.stdin func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exitCh chan bool) { - //tells other go routine quit + // tells other go routine quit defer setQuit(exitCh) for { select { case <-exitCh: return default: - //read websocket msg + // read websocket msg _, wsData, err := wsConn.ReadMessage() if err != nil { logrus.WithError(err).Error("reading webSocket message failed") @@ -317,15 +316,15 @@ func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exit switch msgObj.Type { case wsMsgResize: - //handle xterm.js size change + // handle xterm.js size change if msgObj.Cols > 0 && msgObj.Rows > 0 { if err := ssConn.Session.WindowChange(msgObj.Rows, msgObj.Cols); err != nil { logrus.WithError(err).Error("ssh pty change windows size failed") } } case wsMsgCmd: - //handle xterm.js stdin - //decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) + // handle xterm.js stdin + // decodeBytes, err := base64.StdEncoding.DecodeString(msgObj.Cmd) decodeBytes := []byte(msgObj.Cmd) if err != nil { logrus.WithError(err).Error("websock cmd string base64 decoding failed") @@ -333,7 +332,7 @@ func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exit if _, err := ssConn.StdinPipe.Write(decodeBytes); err != nil { logrus.WithError(err).Error("ws cmd bytes write to ssh.stdin pipe failed") } - //write input cmd to log buffer + // write input cmd to log buffer if _, err := logBuff.Write(decodeBytes); err != nil { logrus.WithError(err).Error("write received cmd into log buffer failed") } @@ -341,6 +340,7 @@ func (ssConn *SshConn) Login(wsConn *websocket.Conn, logBuff *bytes.Buffer, exit } } } + func (ssConn *SshConn) SessionWait(quitChan chan bool) { if err := ssConn.Session.Wait(); err != nil { logrus.WithError(err).Error("ssh session wait failed") @@ -395,7 +395,7 @@ func WsReaderCopy(reader *websocket.Conn, writer io.Writer) { if err = json2.Unmarshal(p, &msgObj); err != nil { writer.Write(p) } else if msgObj.Type == wsMsgResize { - //writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r")) + // writer.Write([]byte("stty rows " + strconv.Itoa(msgObj.Rows) + " && stty cols " + strconv.Itoa(msgObj.Cols) + " \r")) } } } diff --git a/pkg/utils/command/command_helper.go b/pkg/utils/command/command_helper.go index 9a2fded41..a47b2888f 100644 --- a/pkg/utils/command/command_helper.go +++ b/pkg/utils/command/command_helper.go @@ -35,8 +35,8 @@ func ExecResultStrArray(cmdStr string) []string { fmt.Println(err) return nil } - //str, err := ioutil.ReadAll(stdout) - var networklist = []string{} + // str, err := ioutil.ReadAll(stdout) + networklist := []string{} outputBuf := bufio.NewReader(stdout) for { output, _, err := outputBuf.ReadLine() @@ -54,6 +54,8 @@ func ExecResultStrArray(cmdStr string) []string { func ExecResultStr(cmdStr string) string { cmd := exec.Command("/bin/bash", "-c", cmdStr) + println(cmd.String()) + stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) @@ -73,7 +75,7 @@ func ExecResultStr(cmdStr string) string { return string(str) } -//执行 lsblk 命令 +// 执行 lsblk 命令 func ExecLSBLK() []byte { output, err := exec.Command("lsblk", "-O", "-J", "-b").Output() if err != nil { @@ -83,7 +85,7 @@ func ExecLSBLK() []byte { return output } -//执行 lsblk 命令 +// 执行 lsblk 命令 func ExecLSBLKByPath(path string) []byte { output, err := exec.Command("lsblk", path, "-O", "-J", "-b").Output() if err != nil { @@ -93,7 +95,7 @@ func ExecLSBLKByPath(path string) []byte { return output } -//exec smart +// exec smart func ExecSmartCTLByPath(path string) []byte { timeout := 3 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) @@ -107,6 +109,5 @@ func ExecSmartCTLByPath(path string) []byte { } func ExecEnabledSMART(path string) { - exec.Command("smartctl", "-s on", path).Output() } diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index b08dcda80..e7fed65e5 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "io/fs" "io/ioutil" "log" "mime/multipart" @@ -60,7 +61,7 @@ func MkDir(src string) error { if err != nil { return err } - os.Chmod(src, 0777) + os.Chmod(src, 0o777) return nil } @@ -103,7 +104,7 @@ func MustOpen(fileName, filePath string) (*os.File, error) { return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err) } - f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) + f, err := Open(src+fileName, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o644) if err != nil { return nil, fmt.Errorf("Fail to OpenFile :%v", err) } @@ -113,7 +114,7 @@ func MustOpen(fileName, filePath string) (*os.File, error) { // 判断所给路径文件/文件夹是否存在 func Exists(path string) bool { - _, err := os.Stat(path) //os.Stat获取文件信息 + _, err := os.Stat(path) // os.Stat获取文件信息 if err != nil { if os.IsExist(err) { return true @@ -147,7 +148,7 @@ func CreateFile(path string) error { } func CreateFileAndWriteContent(path string, content string) error { - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666) + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o666) if err != nil { return err } @@ -163,7 +164,7 @@ func CreateFileAndWriteContent(path string, content string) error { // IsNotExistMkDir create a directory if it does not exist func IsNotExistCreateFile(src string) error { - if notExist := CheckNotExist(src); notExist == true { + if notExist := CheckNotExist(src); notExist { if err := CreateFile(src); err != nil { return err } @@ -267,7 +268,7 @@ func CopySingleFile(src, dst, style string) error { return os.Chmod(dst, srcinfo.Mode()) } -//Check for duplicate file names +// Check for duplicate file names func GetNoDuplicateFileName(fullPath string) string { path, fileName := filepath.Split(fullPath) fileSuffix := path2.Ext(fileName) @@ -293,7 +294,7 @@ func CopyDir(src string, dst string, style string) error { } return nil } - //dstPath := dst + // dstPath := dst lastPath := src[strings.LastIndex(src, "/")+1:] dst += "/" + lastPath // for i := 0; Exists(dst); i++ { @@ -314,7 +315,7 @@ func CopyDir(src string, dst string, style string) error { } for _, fd := range fds { srcfp := path.Join(src, fd.Name()) - dstfp := dst //path.Join(dst, fd.Name()) + dstfp := dst // path.Join(dst, fd.Name()) if fd.IsDir() { if err = CopyDir(srcfp, dstfp, style); err != nil { @@ -336,10 +337,17 @@ func WriteToPath(data []byte, path, name string) error { } else { fullPath += "/" + name } - IsNotExistCreateFile(fullPath) + return WriteToFullPath(data, fullPath, 0o666) +} + +func WriteToFullPath(data []byte, fullPath string, perm fs.FileMode) error { + if err := IsNotExistCreateFile(fullPath); err != nil { + return err + } + file, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, - 0666, + perm, ) if err != nil { return err @@ -350,16 +358,15 @@ func WriteToPath(data []byte, path, name string) error { return err } -//最终拼接 +// 最终拼接 func SpliceFiles(dir, path string, length int, startPoint int) error { - fullPath := path IsNotExistCreateFile(fullPath) file, _ := os.OpenFile(fullPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, - 0666, + 0o666, ) defer file.Close() bufferedWriter := bufio.NewWriter(file) @@ -380,7 +387,6 @@ func SpliceFiles(dir, path string, length int, startPoint int) error { } func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) { - switch t { case "zip", "": return ".zip", archiver.NewZip(), nil @@ -400,8 +406,8 @@ func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) { return "", nil, errors.New("format not implemented") } } -func AddFile(ar archiver.Writer, path, commonPath string) error { +func AddFile(ar archiver.Writer, path, commonPath string) error { info, err := os.Stat(path) if err != nil { return err @@ -447,6 +453,7 @@ func AddFile(ar archiver.Writer, path, commonPath string) error { return nil } + func CommonPrefix(sep byte, paths ...string) string { // Handle special cases. switch len(paths) { @@ -513,7 +520,7 @@ func GetFileOrDirSize(path string) (int64, error) { return fileInfo.Size(), nil } -//getFileSize get file size by path(B) +// getFileSize get file size by path(B) func DirSizeB(path string) (int64, error) { var size int64 err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { diff --git a/route/route.go b/route/route.go index 110fd6992..8b254f892 100644 --- a/route/route.go +++ b/route/route.go @@ -11,7 +11,6 @@ import ( ) func InitRouter() *gin.Engine { - r := gin.Default() r.Use(middleware.Cors()) @@ -35,7 +34,7 @@ func InitRouter() *gin.Engine { // r.GET("/v1/users/image", v1.GetUserImage) // r.GET("/v1/users/status", v1.GetUserStatus) //init/check - //r.GET("/v1/guide/check", v1.GetGuideCheck) // /v1/sys/guide_check + // r.GET("/v1/guide/check", v1.GetGuideCheck) // /v1/sys/guide_check r.GET("/v1/sys/debug", v1.GetSystemConfigDebug) // //debug r.GET("/v1/sys/socket-port", v1.GetSystemSocketPort) //sys/socket_port @@ -73,7 +72,7 @@ func InitRouter() *gin.Engine { v1AppsGroup := v1Group.Group("/apps") v1AppsGroup.Use() { - v1AppsGroup.GET("", v1.AppList) //list + v1AppsGroup.GET("", v1.AppList) // list v1AppsGroup.GET("/:id", v1.AppInfo) } v1ContainerGroup := v1Group.Group("/container") @@ -84,24 +83,24 @@ func InitRouter() *gin.Engine { v1ContainerGroup.GET("/usage", v1.AppUsageList) v1ContainerGroup.GET("/:id", v1.ContainerUpdateInfo) ///update/:id/info v1ContainerGroup.GET("/:id/logs", v1.ContainerLog) // /app/logs/:id - v1ContainerGroup.GET("/networks", v1.GetDockerNetworks) //app/install/config + v1ContainerGroup.GET("/networks", v1.GetDockerNetworks) // app/install/config - v1ContainerGroup.GET("/:id/state", v1.GetContainerState) //app/state/:id ?state=install_progress + v1ContainerGroup.GET("/:id/state", v1.GetContainerState) // app/state/:id ?state=install_progress // there are problems, temporarily do not deal with - v1ContainerGroup.GET("/:id/terminal", v1.DockerTerminal) //app/terminal/:id - v1ContainerGroup.POST("", v1.InstallApp) //app/install - //v1ContainerGroup.GET("/:id", v1.ContainerInfo) // /app/info/:id + v1ContainerGroup.GET("/:id/terminal", v1.DockerTerminal) // app/terminal/:id + v1ContainerGroup.POST("", v1.InstallApp) // app/install + // v1ContainerGroup.GET("/:id", v1.ContainerInfo) // /app/info/:id v1ContainerGroup.PUT("/:id", v1.UpdateSetting) ///update/:id/setting v1ContainerGroup.PUT("/:id/state", v1.ChangAppState) // /app/state/:id - v1ContainerGroup.DELETE("/:id", v1.UnInstallApp) //app/uninstall/:id - //Not used + v1ContainerGroup.DELETE("/:id", v1.UnInstallApp) // app/uninstall/:id + // Not used v1ContainerGroup.PUT("/:id/latest", v1.PutAppUpdate) - //Not used + // Not used v1ContainerGroup.POST("/share", v1.ShareAppFile) - v1ContainerGroup.GET("/info", v1.GetcontainerInfo) - v1ContainerGroup.PUT("/info", v1.PutcontainerInfo) + v1ContainerGroup.GET("/info", v1.GetDockerDaemonConfiguration) + v1ContainerGroup.PUT("/info", v1.PutDockerDaemonConfiguration) } v1AppCategoriesGroup := v1Group.Group("/app-categories") @@ -113,19 +112,19 @@ func InitRouter() *gin.Engine { v1SysGroup := v1Group.Group("/sys") v1SysGroup.Use() { - v1SysGroup.GET("/version", v1.GetSystemCheckVersion) //version/check + v1SysGroup.GET("/version", v1.GetSystemCheckVersion) // version/check v1SysGroup.POST("/update", v1.SystemUpdate) - v1SysGroup.GET("/hardware", v1.GetSystemHardwareInfo) //hardware/info + v1SysGroup.GET("/hardware", v1.GetSystemHardwareInfo) // hardware/info v1SysGroup.GET("/wsssh", v1.WsSsh) v1SysGroup.POST("/ssh-login", v1.PostSshLogin) - //v1SysGroup.GET("/config", v1.GetSystemConfig) //delete - //v1SysGroup.POST("/config", v1.PostSetSystemConfig) - v1SysGroup.GET("/logs", v1.GetCasaOSErrorLogs) //error/logs - //v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)//delete - //v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)//delete + // v1SysGroup.GET("/config", v1.GetSystemConfig) //delete + // v1SysGroup.POST("/config", v1.PostSetSystemConfig) + v1SysGroup.GET("/logs", v1.GetCasaOSErrorLogs) // error/logs + // v1SysGroup.GET("/widget/config", v1.GetWidgetConfig)//delete + // v1SysGroup.POST("/widget/config", v1.PostSetWidgetConfig)//delete v1SysGroup.POST("/stop", v1.PostKillCasaOS) @@ -141,31 +140,31 @@ func InitRouter() *gin.Engine { v1SysGroup.GET("/server-info", nil) v1SysGroup.PUT("/server-info", nil) v1SysGroup.GET("/apps-state", v1.GetSystemAppsStatus) - //v1SysGroup.GET("/port", v1.GetCasaOSPort) - //v1SysGroup.PUT("/port", v1.PutCasaOSPort) + // v1SysGroup.GET("/port", v1.GetCasaOSPort) + // v1SysGroup.PUT("/port", v1.PutCasaOSPort) v1SysGroup.GET("/proxy", v1.GetSystemProxy) } v1PortGroup := v1Group.Group("/port") v1PortGroup.Use() { - v1PortGroup.GET("/", v1.GetPort) //app/port - v1PortGroup.GET("/state/:port", v1.PortCheck) //app/check/:port + v1PortGroup.GET("/", v1.GetPort) // app/port + v1PortGroup.GET("/state/:port", v1.PortCheck) // app/check/:port } v1FileGroup := v1Group.Group("/file") v1FileGroup.Use() { - v1FileGroup.GET("", v1.GetDownloadSingleFile) //download/:path + v1FileGroup.GET("", v1.GetDownloadSingleFile) // download/:path v1FileGroup.POST("", v1.PostCreateFile) v1FileGroup.PUT("", v1.PutFileContent) v1FileGroup.PUT("/name", v1.RenamePath) - //file/rename - v1FileGroup.GET("/content", v1.GetFilerContent) //file/read + // file/rename + v1FileGroup.GET("/content", v1.GetFilerContent) // file/read - //File uploads need to be handled separately, and will not be modified here + // File uploads need to be handled separately, and will not be modified here v1FileGroup.POST("/upload", v1.PostFileUpload) v1FileGroup.GET("/upload", v1.GetFileUpload) - //v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) + // v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) } v1FolderGroup := v1Group.Group("/folder") v1FolderGroup.Use() @@ -178,9 +177,9 @@ func InitRouter() *gin.Engine { v1BatchGroup.Use() { - v1BatchGroup.DELETE("", v1.DeleteFile) //file/delete + v1BatchGroup.DELETE("", v1.DeleteFile) // file/delete v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir) - v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) //file/operate + v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) // file/operate v1BatchGroup.GET("", v1.GetDownloadFile) } v1ImageGroup := v1Group.Group("/image") @@ -211,7 +210,7 @@ func InitRouter() *gin.Engine { v1NotifyGroup.Use() { v1NotifyGroup.POST("/:path", v1.PostNotifyMessage) - //merge to system + // merge to system v1NotifyGroup.POST("/system_status", v1.PostSystemStatusNotify) } } diff --git a/route/v1/app.go b/route/v1/app.go index cc2ee009d..dec60ef4a 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -2,8 +2,9 @@ package v1 import ( "encoding/json" - "fmt" "io/ioutil" + "net/http" + "path/filepath" "strconv" "github.com/IceWhaleTech/CasaOS/model" @@ -16,6 +17,10 @@ import ( "github.com/gin-gonic/gin" ) +const ( + dockerDaemonConfigurationFilePath = "/etc/docker/daemon.json" +) + // @Summary 获取远程列表 // @Produce application/json // @Accept application/json @@ -29,8 +34,7 @@ import ( // @Success 200 {string} string "ok" // @Router /app/list [get] func AppList(c *gin.Context) { - - //service.MyService.Docker().DockerContainerCommit("test2") + // service.MyService.Docker().DockerContainerCommit("test2") index := c.DefaultQuery("index", "1") size := c.DefaultQuery("size", "10000") @@ -139,7 +143,7 @@ func MyAppList(c *gin.Context) { func AppUsageList(c *gin.Context) { list := service.MyService.App().GetHardwareUsage() c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) - //c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: nil}) + // c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: nil}) } // @Summary 应用详情 @@ -151,7 +155,6 @@ func AppUsageList(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /app/appinfo/{id} [get] func AppInfo(c *gin.Context) { - id := c.Param("id") language := c.GetHeader("Language") info, err := service.MyService.Casa().GetServerAppInfo(id, "", language) @@ -213,7 +216,7 @@ func AppInfo(c *gin.Context) { // return c1.Type < c2.Type // } - //sort + // sort // if info.NetworkModel != "host" { // sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts) // sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts) @@ -265,53 +268,89 @@ func ShareAppFile(c *gin.Context) { c.JSON(common_err.SUCCESS, json.RawMessage(content)) } -func GetcontainerInfo(c *gin.Context) { +func GetDockerDaemonConfiguration(c *gin.Context) { // info, err := service.MyService.Docker().GetDockerInfo() // if err != nil { // c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) // return // } - daemon := model.DeckerDaemonModel{} + dockerConfig := model.DockerDaemonConfigurationModel{} data := make(map[string]interface{}, 1) data["docker_root_dir"] = "" - if file.Exists("/etc/docker/daemon.json") { - byteResult := file.ReadFullFile("/etc/docker/daemon.json") - err := json.Unmarshal(byteResult, &daemon) + + // TODO read dockerRootDir from /etc/casaos/casaos.conf + if file.Exists(dockerDaemonConfigurationFilePath) { + byteResult := file.ReadFullFile(dockerDaemonConfigurationFilePath) + err := json.Unmarshal(byteResult, &dockerConfig) if err != nil { c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) return } - data["docker_root_dir"] = daemon.Graph + + if dockerConfig.Root != "" { + data["docker_root_dir"] = dockerConfig.Root + } else { + data["docker_root_dir"] = "/var/lib/docker" + } } c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } -func PutcontainerInfo(c *gin.Context) { + +func PutDockerDaemonConfiguration(c *gin.Context) { js := make(map[string]interface{}) - err := c.BindJSON(&js) - if err != nil { - c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + if err := c.BindJSON(&js); err != nil { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + return + } + + value, ok := js["docker_root_dir"] + if !ok { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "`docker_root_dir` should not empty"}) return } - dockerRootDir := js["docker_root_dir"].(string) - daemon := model.DeckerDaemonModel{} - if file.Exists("/etc/docker/daemon.json") { - byteResult := file.ReadFullFile("/etc/docker/daemon.json") - err := json.Unmarshal(byteResult, &daemon) + + dockerConfig := model.DockerDaemonConfigurationModel{} + if file.Exists(dockerDaemonConfigurationFilePath) { + byteResult := file.ReadFullFile(dockerDaemonConfigurationFilePath) + err := json.Unmarshal(byteResult, &dockerConfig) if err != nil { - c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to deserialize " + dockerDaemonConfigurationFilePath, Data: err.Error()}) return } } - if !file.Exists(dockerRootDir) { - c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS), Data: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) + + dockerRootDir := value.(string) + if dockerRootDir == "/" { + dockerConfig.Root = "" // omitempty - empty string will not be serialized + } else { + if !file.Exists(dockerRootDir) { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS), Data: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) + return + } + + dockerConfig.Root = filepath.Join(dockerRootDir, "docker") + + if err := file.IsNotExistMkDir(dockerConfig.Root); err != nil { + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to create " + dockerConfig.Root, Data: err.Error()}) + return + } + } + + byteMode, err := json.Marshal(dockerConfig) + if err != nil { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker config", Data: dockerConfig}) return } - daemon.Graph = dockerRootDir - byteMode, _ := json.Marshal(daemon) - file.WriteToPath(byteMode, "/etc/docker", "daemon.json") - fmt.Println(command.ExecResultStr("systemctl daemon-reload")) - fmt.Println(command.ExecResultStr("systemctl restart docker")) + if err := file.WriteToFullPath(byteMode, dockerDaemonConfigurationFilePath, 0o644); err != nil { + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write to " + dockerDaemonConfigurationFilePath, Data: err.Error()}) + return + } + + // TODO also write dockerRootDir to /etc/casaos/casaos.conf + + println(command.ExecResultStr("systemctl daemon-reload")) + println(command.ExecResultStr("systemctl restart docker")) - c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: js}) + c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: js}) } From cbbb907d6aa1bce9741c2b03791dab6a4672f3f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 11 Oct 2022 16:55:20 -0400 Subject: [PATCH 18/21] wip --- route/v1/app.go | 55 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/route/v1/app.go b/route/v1/app.go index dec60ef4a..8e3934786 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -18,6 +18,7 @@ import ( ) const ( + dockerRootDirFilePath = "/var/lib/casaos/docker_root" dockerDaemonConfigurationFilePath = "/etc/docker/daemon.json" ) @@ -274,36 +275,27 @@ func GetDockerDaemonConfiguration(c *gin.Context) { // c.JSON(common_err.SERVICE_ERROR, &model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) // return // } - dockerConfig := model.DockerDaemonConfigurationModel{} - data := make(map[string]interface{}, 1) - data["docker_root_dir"] = "" + data := make(map[string]interface{}) - // TODO read dockerRootDir from /etc/casaos/casaos.conf - if file.Exists(dockerDaemonConfigurationFilePath) { - byteResult := file.ReadFullFile(dockerDaemonConfigurationFilePath) - err := json.Unmarshal(byteResult, &dockerConfig) + if file.Exists(dockerRootDirFilePath) { + buf := file.ReadFullFile(dockerRootDirFilePath) + err := json.Unmarshal(buf, &data) if err != nil { - c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + c.JSON(common_err.CLIENT_ERROR, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err}) return } - - if dockerConfig.Root != "" { - data["docker_root_dir"] = dockerConfig.Root - } else { - data["docker_root_dir"] = "/var/lib/docker" - } } c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } func PutDockerDaemonConfiguration(c *gin.Context) { - js := make(map[string]interface{}) - if err := c.BindJSON(&js); err != nil { - c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err.Error()}) + request := make(map[string]interface{}) + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: err}) return } - value, ok := js["docker_root_dir"] + value, ok := request["docker_root_dir"] if !ok { c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS), Data: "`docker_root_dir` should not empty"}) return @@ -314,7 +306,7 @@ func PutDockerDaemonConfiguration(c *gin.Context) { byteResult := file.ReadFullFile(dockerDaemonConfigurationFilePath) err := json.Unmarshal(byteResult, &dockerConfig) if err != nil { - c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to deserialize " + dockerDaemonConfigurationFilePath, Data: err.Error()}) + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to deserialize " + dockerDaemonConfigurationFilePath, Data: err}) return } } @@ -331,26 +323,33 @@ func PutDockerDaemonConfiguration(c *gin.Context) { dockerConfig.Root = filepath.Join(dockerRootDir, "docker") if err := file.IsNotExistMkDir(dockerConfig.Root); err != nil { - c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to create " + dockerConfig.Root, Data: err.Error()}) + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to create " + dockerConfig.Root, Data: err}) return } } - byteMode, err := json.Marshal(dockerConfig) - if err != nil { - c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker config", Data: dockerConfig}) + if buf, err := json.Marshal(request); err != nil { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker root json", Data: err}) return + } else { + if err := file.WriteToFullPath(buf, dockerRootDirFilePath, 0o644); err != nil { + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write " + dockerRootDirFilePath, Data: err}) + return + } } - if err := file.WriteToFullPath(byteMode, dockerDaemonConfigurationFilePath, 0o644); err != nil { - c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write to " + dockerDaemonConfigurationFilePath, Data: err.Error()}) + if buf, err := json.Marshal(dockerConfig); err != nil { + c.JSON(http.StatusBadRequest, &model.Result{Success: common_err.CLIENT_ERROR, Message: "error when trying to serialize docker config", Data: dockerConfig}) return + } else { + if err := file.WriteToFullPath(buf, dockerDaemonConfigurationFilePath, 0o644); err != nil { + c.JSON(http.StatusInternalServerError, &model.Result{Success: common_err.SERVICE_ERROR, Message: "error when trying to write to " + dockerDaemonConfigurationFilePath, Data: err}) + return + } } - // TODO also write dockerRootDir to /etc/casaos/casaos.conf - println(command.ExecResultStr("systemctl daemon-reload")) println(command.ExecResultStr("systemctl restart docker")) - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: js}) + c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: request}) } From dd66f731572d7bec72d33706e6ece7deb479a07a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 11 Oct 2022 19:12:12 -0400 Subject: [PATCH 19/21] wip --- middleware/gin.go | 64 ------------------------- pkg/utils/file/file.go | 12 +++-- route/route.go | 20 ++++++-- route/v1/file.go | 106 +++++++++++++++++++++++++++-------------- 4 files changed, 94 insertions(+), 108 deletions(-) delete mode 100644 middleware/gin.go diff --git a/middleware/gin.go b/middleware/gin.go deleted file mode 100644 index a9b07b680..000000000 --- a/middleware/gin.go +++ /dev/null @@ -1,64 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-10-08 10:29:08 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-22 11:06:07 - * @FilePath: /CasaOS/middleware/gin.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package middleware - -import ( - "fmt" - "net/http" - "runtime/debug" - "strings" - - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" - "github.com/gin-gonic/gin" - "go.uber.org/zap" -) - -func Cors() gin.HandlerFunc { - return func(c *gin.Context) { - method := c.Request.Method - - c.Header("Access-Control-Allow-Origin", "*") - c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") - // 允许跨域设置可以返回其他子段,可以自定义字段 - c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language,Content-Type,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Connection,Host,Origin,Referer,User-Agent,X-Requested-With") - // 允许浏览器(客户端)可以解析的头部 (重要) - c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers") - // c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With") - // 设置缓存时间 - c.Header("Access-Control-Max-Age", "172800") - c.Header("Access-Control-Allow-Credentials", "true") - c.Set("Content-Type", "application/json") - //} - - // 允许类型校验 - if method == "OPTIONS" { - c.JSON(http.StatusOK, "ok!") - } - - defer func() { - if err := recover(); err != nil { - fmt.Println(err) - debug.PrintStack() - } - }() - - c.Next() - } -} - -func WriteLog() gin.HandlerFunc { - return func(c *gin.Context) { - if !strings.Contains(c.Request.URL.String(), "password") { - loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("method", c.Request.Method)) - c.Next() - } - } -} diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index e7fed65e5..1fd9de2e0 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -362,21 +362,27 @@ func WriteToFullPath(data []byte, fullPath string, perm fs.FileMode) error { func SpliceFiles(dir, path string, length int, startPoint int) error { fullPath := path - IsNotExistCreateFile(fullPath) + if err := IsNotExistCreateFile(fullPath); err != nil { + return err + } file, _ := os.OpenFile(fullPath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o666, ) + defer file.Close() + bufferedWriter := bufio.NewWriter(file) + + // todo: here should have a goroutine to remove each partial file after it is read, to save disk space + for i := 0; i < length+startPoint; i++ { data, err := ioutil.ReadFile(dir + "/" + strconv.Itoa(i+startPoint)) if err != nil { return err } - _, err = bufferedWriter.Write(data) - if err != nil { + if _, err := bufferedWriter.Write(data); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster write return err } } diff --git a/route/route.go b/route/route.go index 8b254f892..a876849ea 100644 --- a/route/route.go +++ b/route/route.go @@ -1,8 +1,10 @@ package route import ( + "os" + + "github.com/IceWhaleTech/CasaOS-Common/middleware" "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" - "github.com/IceWhaleTech/CasaOS/middleware" "github.com/IceWhaleTech/CasaOS/pkg/config" v1 "github.com/IceWhaleTech/CasaOS/route/v1" @@ -11,12 +13,22 @@ import ( ) func InitRouter() *gin.Engine { - r := gin.Default() + ginMode := gin.ReleaseMode + if config.ServerInfo.RunMode != "" { + ginMode = config.ServerInfo.RunMode + } + if os.Getenv(gin.EnvGinMode) != "" { + ginMode = os.Getenv(gin.EnvGinMode) + } + gin.SetMode(ginMode) + r := gin.New() + r.Use(gin.Recovery()) r.Use(middleware.Cors()) - r.Use(middleware.WriteLog()) r.Use(gzip.Gzip(gzip.DefaultCompression)) - gin.SetMode(config.ServerInfo.RunMode) + if ginMode != gin.ReleaseMode { + r.Use(middleware.WriteLog()) + } // r.StaticFS("/ui", http.FS(web.Static)) // r.GET("/", WebUIHome) diff --git a/route/v1/file.go b/route/v1/file.go index 396074d8e..64a5f69c2 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -18,9 +18,11 @@ import ( "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/IceWhaleTech/CasaOS/service" "github.com/gin-gonic/gin" uuid "github.com/satori/go.uuid" + "go.uber.org/zap" ) // @Summary 读取文件 @@ -47,7 +49,7 @@ func GetFilerContent(c *gin.Context) { }) return } - //文件读取任务是将文件内容读取到内存中。 + // 文件读取任务是将文件内容读取到内存中。 info, err := ioutil.ReadFile(filePath) if err != nil { c.JSON(common_err.SERVICE_ERROR, model.Result{ @@ -83,7 +85,6 @@ func GetLocalFile(c *gin.Context) { return } c.File(path) - return } // @Summary download @@ -96,7 +97,6 @@ func GetLocalFile(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /file/download [get] func GetDownloadFile(c *gin.Context) { - t := c.Query("format") files := c.Query("files") @@ -135,11 +135,11 @@ func GetDownloadFile(c *gin.Context) { } if !info.IsDir() { - //打开文件 + // 打开文件 fileTmp, _ := os.Open(filePath) defer fileTmp.Close() - //获取文件的名称 + // 获取文件的名称 fileName := path.Base(filePath) c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) c.File(filePath) @@ -179,7 +179,6 @@ func GetDownloadFile(c *gin.Context) { log.Printf("Failed to archive %s: %v", fname, err) } } - } func GetDownloadSingleFile(c *gin.Context) { @@ -202,7 +201,7 @@ func GetDownloadSingleFile(c *gin.Context) { defer fileTmp.Close() fileName := path.Base(filePath) - //c.Header("Content-Disposition", "inline") + // c.Header("Content-Disposition", "inline") c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) c.File(filePath) } @@ -248,7 +247,7 @@ func DirPath(c *gin.Context) { info[i].Extensions = ex } } - //Hide the files or folders in operation + // Hide the files or folders in operation fileQueue := make(map[string]string) if len(service.OpStrArr) > 0 { for _, v := range service.OpStrArr { @@ -361,7 +360,6 @@ func PostCreateFile(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /file/upload [get] func GetFileUpload(c *gin.Context) { - relative := c.Query("relativePath") fileName := c.Query("filename") chunkNumber := c.Query("chunkNumber") @@ -405,55 +403,92 @@ func PostFileUpload(c *gin.Context) { hash := file.GetHashByContent([]byte(fileName)) if len(path) == 0 { - c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + loger.Error("path should not be empty") + c.JSON(http.StatusBadRequest, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } + tempDir := filepath.Join(path, ".temp", hash+strconv.Itoa(totalChunks)) + "/" if fileName != relative { dirPath = strings.TrimSuffix(relative, fileName) tempDir += dirPath - file.MkDir(path + "/" + dirPath) + if err := file.MkDir(path + "/" + dirPath); err != nil { + loger.Error("error when trying to create `"+path+"/"+dirPath+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } } path += "/" + relative if !file.CheckNotExist(tempDir + chunkNumber) { - file.RMDir(tempDir + chunkNumber) + if err := file.RMDir(tempDir + chunkNumber); err != nil { + loger.Error("error when trying to remove existing `"+tempDir+chunkNumber+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } } if totalChunks > 1 { - file.IsNotExistMkDir(tempDir) + if err := file.IsNotExistMkDir(tempDir); err != nil { + loger.Error("error when trying to create `"+tempDir+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } + + out, err := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0o644) + if err != nil { + loger.Error("error when trying to open `"+tempDir+chunkNumber+"` for creation", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } - out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644) defer out.Close() - _, err := io.Copy(out, f) + + if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy + loger.Error("error when trying to write to `"+tempDir+chunkNumber+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } + + fileNum, err := ioutil.ReadDir(tempDir) if err != nil { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + loger.Error("error when trying to read number of files under `"+tempDir+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return } + + if totalChunks == len(fileNum) { + if err := file.SpliceFiles(tempDir, path, totalChunks, 1); err != nil { + loger.Error("error when trying to splice files under `"+tempDir+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } + + if err := file.RMDir(tempDir); err != nil { + loger.Error("error when trying to remove `"+tempDir+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) + return + } + } } else { - out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) - defer out.Close() - _, err := io.Copy(out, f) + out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644) if err != nil { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + loger.Error("error when trying to open `"+path+"` for creation", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: err.Error()}) return } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) - return - } - fileNum, err := ioutil.ReadDir(tempDir) - if err != nil { - c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) - return - } - if totalChunks == len(fileNum) { - file.SpliceFiles(tempDir, path, totalChunks, 1) - file.RMDir(tempDir) - } - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) + defer out.Close() + + if _, err := io.Copy(out, f); err != nil { // recommend to use https://github.com/iceber/iouring-go for faster copy + loger.Error("error when trying to write to `"+path+"`", zap.Error(err)) + c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + return + } + } + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } // @Summary copy or move file @@ -465,7 +500,6 @@ func PostFileUpload(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /file/operate [post] func PostOperateFileOrDir(c *gin.Context) { - list := model.FileOperate{} c.ShouldBind(&list) @@ -515,7 +549,6 @@ func PostOperateFileOrDir(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /file/delete [delete] func DeleteFile(c *gin.Context) { - paths := []string{} c.ShouldBind(&paths) if len(paths) == 0 { @@ -547,7 +580,6 @@ func DeleteFile(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /file/update [put] func PutFileContent(c *gin.Context) { - fi := model.FileUpdate{} c.ShouldBind(&fi) @@ -557,7 +589,7 @@ func PutFileContent(c *gin.Context) { c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) return } - //err := os.Remove(path) + // err := os.Remove(path) err := os.RemoveAll(fi.FilePath) if err != nil { c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.FILE_DELETE_ERROR, Message: common_err.GetMsg(common_err.FILE_DELETE_ERROR), Data: err}) From 0f3d3e82f56d09e162b61c29e021121e8f608e6b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 11 Oct 2022 23:23:21 -0400 Subject: [PATCH 20/21] wip --- .../migration/script.d/03-migrate-casaos.sh | 64 +++--- .../migration/service.d/casaos/migration.list | 7 +- cmd/migration-tool/main.go | 10 +- cmd/migration-tool/migration-034-035.go | 182 ------------------ cmd/migration-tool/migration-036.go | 74 ------- 5 files changed, 37 insertions(+), 300 deletions(-) delete mode 100644 cmd/migration-tool/migration-034-035.go delete mode 100644 cmd/migration-tool/migration-036.go diff --git a/build/scripts/migration/script.d/03-migrate-casaos.sh b/build/scripts/migration/script.d/03-migrate-casaos.sh index a48c43765..719ff6008 100644 --- a/build/scripts/migration/script.d/03-migrate-casaos.sh +++ b/build/scripts/migration/script.d/03-migrate-casaos.sh @@ -60,8 +60,6 @@ BUILD_PATH=$(dirname "${BASH_SOURCE[0]}")/../../.. SOURCE_ROOT=${BUILD_PATH}/sysroot APP_NAME="casaos" -APP_NAME_FORMAL="CasaOS" -#APP_NAME_FORMAL="casaos-alpha" # check if migration is needed SOURCE_BIN_PATH=${SOURCE_ROOT}/usr/bin @@ -85,6 +83,25 @@ if [ "${NEED_MIGRATION}" = "false" ]; then exit 0 fi +ARCH="unknown" + +case $(uname -m) in + x86_64) + ARCH="amd64" + ;; + aarch64) + ARCH="arm64" + ;; + armv7l) + ARCH="arm-7" + ;; + *) + __error "Unsupported architecture" + ;; +esac + +__info "ARCH: ${ARCH}" + MIGRATION_SERVICE_DIR=${1} if [ -z "${MIGRATION_SERVICE_DIR}" ]; then @@ -95,10 +112,10 @@ MIGRATION_PATH=() CURRENT_VERSION_FOUND="false" -# a VERSION_PAIR looks like "v0.3.5 v0.3.6-alpha2" +# a VERSION_PAIR looks like "v0.3.5 " # # - "v0.3.5" is the current version installed on this host -# - "v0.3.6-alpha2" is the version of the migration tool from GitHub +# - "" is the url of the migration tool while read -r VERSION_PAIR; do if [ -z "${VERSION_PAIR}" ]; then continue @@ -107,15 +124,15 @@ while read -r VERSION_PAIR; do # obtain "v0.3.5" from "v0.3.5 v0.3.6-alpha2" VER1=$(echo "${VERSION_PAIR}" | cut -d' ' -f1) - # obtain "v0.3.6-alpha2" from "v0.3.5 v0.3.6-alpha2" - VER2=$(echo "${VERSION_PAIR}" | cut -d' ' -f2) + # obtain "" from "v0.3.5 " + URL=$(eval echo "${VERSION_PAIR}" | cut -d' ' -f2) if [ "${CURRENT_VERSION}" = "${VER1// /}" ] || [ "${CURRENT_VERSION}" = "LEGACY_WITHOUT_VERSION" ]; then CURRENT_VERSION_FOUND="true" fi if [ "${CURRENT_VERSION_FOUND}" = "true" ]; then - MIGRATION_PATH+=("${VER2// /}") + MIGRATION_PATH+=("${URL// /}") fi done < "${MIGRATION_LIST_FILE}" @@ -124,39 +141,18 @@ if [ ${#MIGRATION_PATH[@]} -eq 0 ]; then exit 0 fi -ARCH="unknown" - -case $(uname -m) in - x86_64) - ARCH="amd64" - ;; - aarch64) - ARCH="arm64" - ;; - armv7l) - ARCH="arm-7" - ;; - *) - __error "Unsupported architecture" - ;; -esac - pushd "${MIGRATION_SERVICE_DIR}" -{ for VER2 in "${MIGRATION_PATH[@]}"; do - - - MIGRATION_TOOL_FILE=linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz +{ for URL in "${MIGRATION_PATH[@]}"; do + MIGRATION_TOOL_FILE=$(basename "${URL}") if [ -f "${MIGRATION_TOOL_FILE}" ]; then __info "Migration tool ${MIGRATION_TOOL_FILE} exists. Skip downloading." continue fi - # MIGRATION_TOOL_URL=http://192.168.2.197:8000/v1/package/migration?type=release&name="${APP_NAME_FORMAL}"&version=${VER2}&arch=${ARCH} - MIGRATION_TOOL_URL=https://github.com/IceWhaleTech/"${APP_NAME_FORMAL}"/releases/download/"${VER2}"/linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz - echo "Dowloading ${MIGRATION_TOOL_URL}..." - curl -sL -O "${MIGRATION_TOOL_URL}" + __info "Dowloading ${URL}..." + curl -fsSL -o "${MIGRATION_TOOL_FILE}" -O "${URL}" done } || { popd @@ -164,8 +160,8 @@ pushd "${MIGRATION_SERVICE_DIR}" } { - for VER2 in "${MIGRATION_PATH[@]}"; do - MIGRATION_TOOL_FILE=linux-"${ARCH}"-"${APP_NAME}"-migration-tool-"${VER2}".tar.gz + for URL in "${MIGRATION_PATH[@]}"; do + MIGRATION_TOOL_FILE=$(basename "${URL}") __info "Extracting ${MIGRATION_TOOL_FILE}..." tar zxvf "${MIGRATION_TOOL_FILE}" || __error "Failed to extract ${MIGRATION_TOOL_FILE}" diff --git a/build/scripts/migration/service.d/casaos/migration.list b/build/scripts/migration/service.d/casaos/migration.list index d3ce03f38..c78028051 100644 --- a/build/scripts/migration/service.d/casaos/migration.list +++ b/build/scripts/migration/service.d/casaos/migration.list @@ -1,4 +1,3 @@ -LEGACY_WITHOUT_VERSION v0.3.6 -v0.3.5 v0.3.6 -v0.3.5.1 v0.3.6 -v0.3.6 v0.3.7 +LEGACY_WITHOUT_VERSION https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz +v0.3.5 https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz +v0.3.5.1 https://github.com/IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz diff --git a/cmd/migration-tool/main.go b/cmd/migration-tool/main.go index 93b065d3e..d28663c0a 100644 --- a/cmd/migration-tool/main.go +++ b/cmd/migration-tool/main.go @@ -83,8 +83,7 @@ func main() { } migrationTools := []interfaces.MigrationTool{ - NewMigrationToolFor_035(), - NewMigrationToolFor_036(), + // nothing to migrate from last version } var selectedMigrationTool interfaces.MigrationTool @@ -115,8 +114,7 @@ func main() { panic(err) } - selectedMigrationTool.PostMigrate() - _logger.Info("casaos migration ok") - // panic(err) - + if err := selectedMigrationTool.PostMigrate(); err != nil { + _logger.Error("Migration succeeded, but post-migration failed: %s", err) + } } diff --git a/cmd/migration-tool/migration-034-035.go b/cmd/migration-tool/migration-034-035.go deleted file mode 100644 index 3dfed609a..000000000 --- a/cmd/migration-tool/migration-034-035.go +++ /dev/null @@ -1,182 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.org - * @Date: 2022-08-24 17:36:00 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-09-05 11:24:27 - * @FilePath: /CasaOS/cmd/migration-tool/migration-034-035.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package main - -import ( - "io" - "io/ioutil" - "os" - "path" - "strings" - - interfaces "github.com/IceWhaleTech/CasaOS-Common" - "github.com/IceWhaleTech/CasaOS-Common/utils/version" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/command" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/service" -) - -type migrationTool036 struct{} - -func (u *migrationTool036) IsMigrationNeeded() (bool, error) { - - majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion() - if err != nil { - if err == version.ErrLegacyVersionNotFound { - return false, nil - } - - return false, err - } - - if majorVersion > 0 { - return false, nil - } - - if minorVersion > 3 { - return false, nil - } - - if minorVersion == 3 && patchVersion > 5 { - return false, nil - } - - _logger.Info("Migration is needed for a CasaOS version 0.3.5 and older...") - return true, nil - -} - -func (u *migrationTool036) PreMigrate() error { - - return nil -} - -func (u *migrationTool036) Migrate() error { - - if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { - service.MyService.System().UpdateUSBAutoMount("False") - service.MyService.System().ExecUSBAutoMountShell("False") - } - newAPIUrl := "https://api.casaos.io/casaos-api" - if config.ServerInfo.ServerApi == "https://api.casaos.zimaboard.com" { - config.ServerInfo.ServerApi = newAPIUrl - config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - command.OnlyExec("curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/assist.sh | bash") - if !file.CheckNotExist("/casaOS") { - command.OnlyExec("source /casaOS/server/shell/update.sh ;") - command.OnlyExec("source " + config.AppInfo.ShellPath + "/delete-old-service.sh ;") - } - - service.MyService.App().ImportApplications(true) - - src := "/casaOS/server/conf/conf.ini" - if file.Exists(src) { - dst := "/etc/casaos/casaos.conf" - source, err := os.Open(src) - if err != nil { - return err - } - defer source.Close() - - destination, err := os.Create(dst) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err - } - - } - - if file.Exists("/casaOS/server/db") { - var fds []os.FileInfo - var err error - to := "/var/lib/casaos/db" - file.IsNotExistMkDir(to) - from := "/casaOS/server/db" - if fds, err = ioutil.ReadDir(from); err != nil { - return err - } - - for _, fd := range fds { - srcfp := path.Join(from, fd.Name()) - dstfp := path.Join(to, fd.Name()) - source, err := os.Open(srcfp) - if err != nil { - return err - } - defer source.Close() - - destination, err := os.Create(dstfp) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err - } - } - - } - - if file.Exists("/casaOS/server/conf") { - var fds []os.FileInfo - var err error - to := "/var/lib/casaos/conf" - file.IsNotExistMkDir(to) - from := "/casaOS/server/conf" - if fds, err = ioutil.ReadDir(from); err != nil { - return err - } - - for _, fd := range fds { - fExt := path.Ext(fd.Name()) - if fExt != ".json" { - continue - } - srcfp := path.Join(from, fd.Name()) - dstfp := path.Join(to, fd.Name()) - source, err := os.Open(srcfp) - if err != nil { - return err - } - defer source.Close() - - destination, err := os.Create(dstfp) - if err != nil { - return err - } - defer destination.Close() - _, err = io.Copy(destination, source) - if err != nil { - return err - } - } - - } - - _logger.Info("update done") - return nil -} - -func (u *migrationTool036) PostMigrate() error { - return nil -} - -func NewMigrationToolFor_035() interfaces.MigrationTool { - return &migrationTool{} -} diff --git a/cmd/migration-tool/migration-036.go b/cmd/migration-tool/migration-036.go deleted file mode 100644 index b6d54103c..000000000 --- a/cmd/migration-tool/migration-036.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.org - * @Date: 2022-08-24 17:36:00 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-09-05 11:24:27 - * @FilePath: /CasaOS/cmd/migration-tool/migration-034-035.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package main - -import ( - "strings" - - interfaces "github.com/IceWhaleTech/CasaOS-Common" - "github.com/IceWhaleTech/CasaOS-Common/utils/version" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/service" -) - -type migrationTool struct{} - -func (u *migrationTool) IsMigrationNeeded() (bool, error) { - - majorVersion, minorVersion, patchVersion, err := version.DetectLegacyVersion() - if err != nil { - if err == version.ErrLegacyVersionNotFound { - return false, nil - } - - return false, err - } - - if majorVersion > 0 { - return false, nil - } - - if minorVersion > 3 { - return false, nil - } - - if minorVersion == 3 && patchVersion > 5 { - return false, nil - } - - _logger.Info("Migration is needed for a CasaOS version 0.3.5 and older...") - return true, nil - -} - -func (u *migrationTool) PreMigrate() error { - - return nil -} - -func (u *migrationTool) Migrate() error { - - if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { - service.MyService.System().UpdateUSBAutoMount("False") - service.MyService.System().ExecUSBAutoMountShell("False") - } - - _logger.Info("update done") - return nil -} - -func (u *migrationTool) PostMigrate() error { - return nil -} - -func NewMigrationToolFor_036() interfaces.MigrationTool { - return &migrationTool{} -} From b61a3db611efee5a729ea2b8715eee0108984462 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 12 Oct 2022 16:12:14 -0400 Subject: [PATCH 21/21] wip --- .../service.d/casaos/debian/setup-casaos.sh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh b/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh index e083373c8..50c8d9149 100644 --- a/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh +++ b/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh @@ -31,15 +31,10 @@ if [ ! -f "${CONF_FILE}" ]; then cp -v "${CONF_FILE_SAMPLE}" "${CONF_FILE}" fi -if systemctl is-active "${APP_NAME}.service" &>/dev/null ;then - echo "server started" -else - # enable and start service - systemctl daemon-reload - - echo "Enabling service..." - systemctl enable --force --no-ask-password "${APP_NAME}.service" - - #echo "Starting service..." - #systemctl start --force --no-ask-password "${APP_NAME}.service" -fi \ No newline at end of file +rm -rf /etc/systemd/system/casaos.service # remove old service file + +systemctl daemon-reload + +# enable service (without starting) +echo "Enabling service..." +systemctl enable --force --no-ask-password "${APP_NAME}.service"