Add file sharing function

This commit is contained in:
a624669980@163.com 2022-08-10 13:53:30 +08:00
parent 660b00ec6a
commit 4cfd2ec2f6
34 changed files with 1205 additions and 535 deletions

View File

@ -18,6 +18,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
## [0.3.5-alpha] - 2022-08-08
### Added
- [File] Condivisione samba montata
- [File] Condivisione dei file tramite samba
### Changed
- [Disk] Supporto per il montaggio di dischi dati esistenti
### Fixed
- fixed uninstalling imported docker container apps results in wiping ALL your config data from them ([#360](https://github.com/IceWhaleTech/CasaOS/issues/360))
## [0.3.4] - 2022-07-29(UTC) ## [0.3.4] - 2022-07-29(UTC)
### Added ### Added

2
go.mod
View File

@ -27,6 +27,7 @@ require (
github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/googleapis v1.4.1 // indirect
github.com/golang-jwt/jwt/v4 v4.4.1 github.com/golang-jwt/jwt/v4 v4.4.1
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0
github.com/gomodule/redigo v1.8.5 github.com/gomodule/redigo v1.8.5
github.com/google/go-github/v36 v36.0.0 github.com/google/go-github/v36 v36.0.0
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
@ -56,6 +57,7 @@ require (
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/smartystreets/assertions v1.2.0 // indirect github.com/smartystreets/assertions v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.7.0
github.com/tidwall/gjson v1.10.2 github.com/tidwall/gjson v1.10.2
github.com/tklauser/go-sysconf v0.3.6 // indirect github.com/tklauser/go-sysconf v0.3.6 // indirect
github.com/ugorji/go v1.2.6 // indirect github.com/ugorji/go v1.2.6 // indirect

14
main.go
View File

@ -15,6 +15,7 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/utils/random" "github.com/IceWhaleTech/CasaOS/pkg/utils/random"
"github.com/IceWhaleTech/CasaOS/route" "github.com/IceWhaleTech/CasaOS/route"
"github.com/IceWhaleTech/CasaOS/service" "github.com/IceWhaleTech/CasaOS/service"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/robfig/cron" "github.com/robfig/cron"
"gorm.io/gorm" "gorm.io/gorm"
@ -26,21 +27,31 @@ var configFlag = flag.String("c", "", "config address")
var dbFlag = flag.String("db", "", "db path") var dbFlag = flag.String("db", "", "db path")
var resetUser = flag.Bool("ru", false, "reset user") var resetUser = flag.Bool("ru", false, "reset user")
var user = flag.String("user", "", "user name") var user = flag.String("user", "", "user name")
var version = flag.Bool("v", false, "show version")
func init() { func init() {
flag.Parse() flag.Parse()
if *version {
fmt.Println("v" + types.CURRENTVERSION)
return
}
config.InitSetup(*configFlag) config.InitSetup(*configFlag)
config.UpdateSetup() config.UpdateSetup()
loger.LogInit() loger.LogInit()
if len(*dbFlag) == 0 { if len(*dbFlag) == 0 {
*dbFlag = config.AppInfo.DBPath + "/db" *dbFlag = config.AppInfo.DBPath + "/db"
} }
sqliteDB = sqlite.GetDb(*dbFlag) sqliteDB = sqlite.GetDb(*dbFlag)
//gredis.GetRedisConn(config.RedisInfo), //gredis.GetRedisConn(config.RedisInfo),
service.MyService = service.NewService(sqliteDB) service.MyService = service.NewService(sqliteDB)
service.Cache = cache.Init() service.Cache = cache.Init()
service.GetToken() service.GetToken()
service.NewVersionApp = make(map[string]string) service.NewVersionApp = make(map[string]string)
route.InitFunction() route.InitFunction()
@ -62,6 +73,9 @@ func init() {
// @BasePath /v1 // @BasePath /v1
func main() { func main() {
service.NotifyMsg = make(chan notify.Message, 10) service.NotifyMsg = make(chan notify.Message, 10)
if *version {
return
}
if *resetUser { if *resetUser {
if user == nil || len(*user) == 0 { if user == nil || len(*user) == 0 {
fmt.Println("user is empty") fmt.Println("user is empty")

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.org * @Author: LinkLeong link@icewhale.org
* @Date: 2022-07-27 10:30:43 * @Date: 2022-07-27 10:30:43
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-27 11:36:08 * @LastEditTime: 2022-08-04 20:06:04
* @FilePath: /CasaOS/model/connections.go * @FilePath: /CasaOS/model/connections.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -16,6 +16,5 @@ type Connections struct {
Password string `json:"password,omitempty"` Password string `json:"password,omitempty"`
Host string `json:"host"` Host string `json:"host"`
Port string `json:"port"` Port string `json:"port"`
Directory string `json:"directory"`
MountPoint string `json:"mount_point"` MountPoint string `json:"mount_point"`
} }

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.com * @Author: LinkLeong link@icewhale.com
* @Date: 2022-07-13 10:43:45 * @Date: 2022-07-13 10:43:45
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-29 14:21:59 * @LastEditTime: 2022-08-03 14:45:35
* @FilePath: /CasaOS/model/disk.go * @FilePath: /CasaOS/model/disk.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -63,14 +63,19 @@ type Drive struct {
type DriveUSB struct { type DriveUSB struct {
Name string `json:"name"` Name string `json:"name"`
Size uint64 `json:"size"` Size uint64 `json:"size"`
Used uint64 `json:"use"`
Model string `json:"model"` Model string `json:"model"`
Mount bool `json:"mount"`
Avail uint64 `json:"avail"` 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 { type Storage struct {
MountPoint string `json:"mountpoint"` MountPoint string `json:"mount_point"`
Size string `json:"size"` Size string `json:"size"`
Avail string `json:"avail"` //可用空间 Avail string `json:"avail"` //可用空间
Type string `json:"type"` Type string `json:"type"`

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.org * @Author: LinkLeong link@icewhale.org
* @Date: 2022-05-13 18:15:46 * @Date: 2022-05-13 18:15:46
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-28 13:47:00 * @LastEditTime: 2022-08-01 18:32:57
* @FilePath: /CasaOS/model/zima.go * @FilePath: /CasaOS/model/zima.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -21,5 +21,5 @@ type Path struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
Label string `json:"label,omitempty"` Label string `json:"label,omitempty"`
Write bool `json:"write"` Write bool `json:"write"`
Extensions map[string]string `json:"extensions"` Extensions map[string]interface{} `json:"extensions"`
} }

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.org * @Author: LinkLeong link@icewhale.org
* @Date: 2022-07-27 10:35:29 * @Date: 2022-07-27 10:35:29
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-27 10:40:26 * @LastEditTime: 2022-08-01 13:56:44
* @FilePath: /CasaOS/pkg/samba/smaba.go * @FilePath: /CasaOS/pkg/samba/smaba.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -47,3 +47,29 @@ func ConnectSambaService(host, port, username, password, directory string) error
} }
return errors.New("directory not found") return errors.New("directory not found")
} }
//get share name list
func GetSambaSharesList(host, port, username, password string) ([]string, error) {
conn, err := net.Dial("tcp", host+":"+port)
if err != nil {
return nil, err
}
defer conn.Close()
d := &smb2.Dialer{
Initiator: &smb2.NTLMInitiator{
User: username,
Password: password,
},
}
s, err := d.Dial(conn)
if err != nil {
return nil, err
}
defer s.Logoff()
names, err := s.ListSharenames()
if err != nil {
return nil, err
}
return names, err
}

View File

@ -1,11 +1,13 @@
package route package route
import ( import (
"fmt"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"github.com/IceWhaleTech/CasaOS/pkg/config" "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/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@ -17,13 +19,12 @@ import (
func InitFunction() { func InitFunction() {
ShellInit() ShellInit()
CheckSerialDiskMount() CheckSerialDiskMount()
CheckToken2_11() CheckToken2_11()
ImportApplications() ImportApplications()
// Soon to be removed // Soon to be removed
ChangeAPIUrl() ChangeAPIUrl()
MoveUserToDB() MoveUserToDB()
InitNetworkMount()
} }
func CheckSerialDiskMount() { func CheckSerialDiskMount() {
@ -40,7 +41,7 @@ func CheckSerialDiskMount() {
command.ExecEnabledSMART(v.Path) command.ExecEnabledSMART(v.Path)
if v.Children != nil { if v.Children != nil {
for _, h := range v.Children { for _, h := range v.Children {
if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" { //if len(h.MountPoint) == 0 && len(v.Children) == 1 && h.FsType == "ext4" {
if m, ok := mountPoint[h.UUID]; ok { if m, ok := mountPoint[h.UUID]; ok {
//mount point check //mount point check
volume := m volume := m
@ -58,7 +59,7 @@ func CheckSerialDiskMount() {
} }
} }
} //}
} }
} }
} }
@ -138,3 +139,32 @@ func MoveUserToDB() {
} }
} }
func InitNetworkMount() {
connections := service.MyService.Connections().GetConnectionsList()
for _, v := range connections {
connection := service.MyService.Connections().GetConnectionByID(fmt.Sprint(v.ID))
directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
if err != nil {
service.MyService.Connections().DeleteConnection(fmt.Sprint(connection.ID))
continue
}
baseHostPath := "/mnt/" + connection.Host
mountPointList := service.MyService.System().GetDirPath(baseHostPath)
for _, v := range mountPointList {
service.MyService.Connections().UnmountSmaba(v.Path)
}
os.RemoveAll(baseHostPath)
file.IsNotExistMkDir(baseHostPath)
for _, v := range directories {
mountPoint := baseHostPath + "/" + v
file.IsNotExistMkDir(mountPoint)
service.MyService.Connections().MountSmaba(connection.Username, connection.Host, v, connection.Port, mountPoint, connection.Password)
}
connection.Directories = strings.Join(directories, ",")
service.MyService.Connections().UpdateConnection(&connection)
}
}

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.com * @Author: LinkLeong link@icewhale.com
* @Date: 2022-07-01 15:11:36 * @Date: 2022-07-01 15:11:36
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-21 15:25:07 * @LastEditTime: 2022-08-03 14:49:15
* @FilePath: /CasaOS/route/periodical.go * @FilePath: /CasaOS/route/periodical.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -133,21 +133,14 @@ func SendUSBBySocket() {
temp.Model = v.Model temp.Model = v.Model
temp.Name = v.Name temp.Name = v.Name
temp.Size = v.Size temp.Size = v.Size
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children { for _, child := range v.Children {
if len(child.MountPoint) > 0 { if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail temp.Avail += avail
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
temp.Used += used
} else {
mountTemp = false
} }
} }
temp.Mount = mountTemp
usb = append(usb, temp) usb = append(usb, temp)
} }
} }
@ -250,21 +243,12 @@ func SendAllHardwareStatusBySocket() {
temp.Model = v.Model temp.Model = v.Model
temp.Name = v.Name temp.Name = v.Name
temp.Size = v.Size temp.Size = v.Size
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children { for _, child := range v.Children {
if len(child.MountPoint) > 0 { if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail temp.Avail += avail
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
temp.Used += used
} else {
mountTemp = false
} }
} }
temp.Mount = mountTemp
usb = append(usb, temp) usb = append(usb, temp)
} }
} }

View File

@ -196,6 +196,8 @@ func InitRouter() *gin.Engine {
//v1DisksGroup.POST("", v1.PostMountDisk) //v1DisksGroup.POST("", v1.PostMountDisk)
v1DisksGroup.GET("", v1.GetDiskList) v1DisksGroup.GET("", v1.GetDiskList)
v1DisksGroup.GET("/usb", v1.GetDisksUSBList)
v1DisksGroup.DELETE("/usb", v1.DeleteDiskUSB)
// //format storage // //format storage
// v1DiskGroup.POST("/format", v1.PostDiskFormat) // v1DiskGroup.POST("/format", v1.PostDiskFormat)

View File

@ -1,7 +1,6 @@
package v1 package v1
import ( import (
"fmt"
"net/http" "net/http"
"reflect" "reflect"
"strconv" "strconv"
@ -45,19 +44,12 @@ func GetDiskList(c *gin.Context) {
temp.Model = v.Model temp.Model = v.Model
temp.Name = v.Name temp.Name = v.Name
temp.Size = v.Size temp.Size = v.Size
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children { for _, child := range v.Children {
if len(child.MountPoint) > 0 { if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail temp.Avail += avail
} else {
mountTemp = false
} }
} }
temp.Mount = mountTemp
data = append(data, temp) data = append(data, temp)
} }
} }
@ -189,6 +181,60 @@ func GetDiskList(c *gin.Context) {
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) 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
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 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 // @Summary get disk list
// @Produce application/json // @Produce application/json
// @Accept application/json // @Accept application/json
@ -274,10 +320,10 @@ func PostDiskAddPartition(c *gin.Context) {
js := make(map[string]interface{}) js := make(map[string]interface{})
c.ShouldBind(&js) c.ShouldBind(&js)
path := js["path"].(string) path := js["path"].(string)
name := js["name"].(string) //name := js["name"].(string)
format := js["format"].(bool) format := js["format"].(bool)
if len(name) == 0 || len(path) == 0 { 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)}) c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return return
} }
@ -285,11 +331,14 @@ func PostDiskAddPartition(c *gin.Context) {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)}) c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_BUSYING, Message: common_err.GetMsg(common_err.DISK_BUSYING)})
return return
} }
if !file.CheckNotExist("/DATA/" + name) {
// /mnt/name exist //diskInfo := service.MyService.Disk().GetDiskInfo(path)
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.NAME_NOT_AVAILABLE, Message: common_err.GetMsg(common_err.NAME_NOT_AVAILABLE)})
return // 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" diskMap[path] = "busying"
currentDisk := service.MyService.Disk().GetDiskInfo(path) currentDisk := service.MyService.Disk().GetDiskInfo(path)
if format { if format {
@ -302,33 +351,43 @@ func PostDiskAddPartition(c *gin.Context) {
service.MyService.Disk().AddPartition(path) service.MyService.Disk().AddPartition(path)
} }
formatBool := true // formatBool := true
for formatBool { // for formatBool {
currentDisk = service.MyService.Disk().GetDiskInfo(path) // currentDisk = service.MyService.Disk().GetDiskInfo(path)
fmt.Println(currentDisk.Children) // if len(currentDisk.Children) > 0 {
if len(currentDisk.Children) > 0 { // formatBool = false
formatBool = false // break
break // }
} // time.Sleep(time.Second)
time.Sleep(time.Second) // }
}
currentDisk = service.MyService.Disk().GetDiskInfo(path) currentDisk = service.MyService.Disk().GetDiskInfo(path)
// if len(currentDisk.Children) != 1 { // 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)}) // c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DISK_NEEDS_FORMAT, Message: common_err.GetMsg(common_err.DISK_NEEDS_FORMAT)})
// return // return
// } // }
for i := 0; i < len(currentDisk.Children); i++ { for i := 0; i < len(currentDisk.Children); i++ {
mountPath := "/DATA/" + name childrenName := currentDisk.Children[i].Label
if len(childrenName) == 0 {
childrenName = "Storage_" + currentDisk.Children[i].Name
}
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 := model2.SerialDisk{}
m.MountPoint = mountPath + strconv.Itoa(i) m.MountPoint = mountPath
m.Path = currentDisk.Children[i].Path m.Path = currentDisk.Children[i].Path
m.UUID = currentDisk.Children[i].UUID m.UUID = currentDisk.Children[i].UUID
m.State = 0 m.State = 0
m.CreatedAt = time.Now().Unix() m.CreatedAt = time.Now().Unix()
service.MyService.Disk().SaveMountPoint(m) service.MyService.Disk().SaveMountPoint(m)
//mount dir //mount dir
service.MyService.Disk().MountDisk(currentDisk.Children[i].Path, mountPath+strconv.Itoa(i)) service.MyService.Disk().MountDisk(currentDisk.Children[i].Path, mountPath)
} }
service.MyService.Disk().RemoveLSBLKCache() service.MyService.Disk().RemoveLSBLKCache()
@ -339,7 +398,7 @@ func PostDiskAddPartition(c *gin.Context) {
msg := notify.StorageMessage{} msg := notify.StorageMessage{}
msg.Action = "ADDED" msg.Action = "ADDED"
msg.Path = currentDisk.Children[0].Path msg.Path = currentDisk.Children[0].Path
msg.Volume = "/DATA/" + name msg.Volume = "/DATA/"
msg.Size = currentDisk.Children[0].Size msg.Size = currentDisk.Children[0].Size
msg.Type = currentDisk.Children[0].Tran msg.Type = currentDisk.Children[0].Tran
service.MyService.Notify().SendStorageBySocket(msg) service.MyService.Notify().SendStorageBySocket(msg)

View File

@ -209,7 +209,7 @@ func InstallApp(c *gin.Context) {
dockerImage = m.Image dockerImage = m.Image
dockerImageVersion = "latest" dockerImageVersion = "latest"
} }
m.Image = dockerImage + ":" + dockerImageVersion
for _, u := range m.Ports { for _, u := range m.Ports {
if u.Protocol == "udp" { if u.Protocol == "udp" {
@ -334,11 +334,11 @@ func InstallApp(c *gin.Context) {
return return
} }
for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) { for !service.MyService.Docker().IsExistImage(m.Image) {
time.Sleep(time.Second) time.Sleep(time.Second)
} }
_, err = service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m) _, err = service.MyService.Docker().DockerContainerCreate(m, "")
if err != nil { if err != nil {
//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100) //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
notify := notify.Application{} notify := notify.Application{}
@ -829,7 +829,6 @@ func UpdateSetting(c *gin.Context) {
// c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)}) // c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR_APP_NAME_EXIST, Message: common_err.GetMsg(common_err.ERROR_APP_NAME_EXIST)})
// return // return
// } // }
service.MyService.Docker().DockerContainerStop(id) service.MyService.Docker().DockerContainerStop(id)
portMap, _ := strconv.Atoi(m.PortMap) portMap, _ := strconv.Atoi(m.PortMap)
if !port2.IsPortAvailable(portMap, "tcp") { if !port2.IsPortAvailable(portMap, "tcp") {
@ -874,7 +873,7 @@ func UpdateSetting(c *gin.Context) {
service.MyService.Docker().DockerContainerUpdateName(id, id) service.MyService.Docker().DockerContainerUpdateName(id, id)
//service.MyService.Docker().DockerContainerRemove(id, true) //service.MyService.Docker().DockerContainerRemove(id, true)
containerId, err := service.MyService.Docker().DockerContainerCreate(m.Image, m) containerId, err := service.MyService.Docker().DockerContainerCreate(m, id)
if err != nil { if err != nil {
service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id) service.MyService.Docker().DockerContainerUpdateName(m.ContainerName, id)
service.MyService.Docker().DockerContainerStart(id) service.MyService.Docker().DockerContainerStart(id)

View File

@ -1,6 +1,7 @@
package v1 package v1
import ( import (
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
@ -221,7 +222,7 @@ func DirPath(c *gin.Context) {
shares := service.MyService.Shares().GetSharesList() shares := service.MyService.Shares().GetSharesList()
sharesMap := make(map[string]string) sharesMap := make(map[string]string)
for _, v := range shares { for _, v := range shares {
sharesMap[v.Path] = v.Name sharesMap[v.Path] = fmt.Sprint(v.ID)
} }
if path == "/DATA/AppData" { if path == "/DATA/AppData" {
list := service.MyService.Docker().DockerContainerList() list := service.MyService.Docker().DockerContainerList()
@ -234,11 +235,6 @@ func DirPath(c *gin.Context) {
info[i].Label = v info[i].Label = v
info[i].Type = "application" info[i].Type = "application"
} }
if _, ok := sharesMap[info[i].Path]; ok {
ex := make(map[string]string)
ex["shared"] = "true"
info[i].Extensions = ex
}
} }
} else if path == "/DATA" { } else if path == "/DATA" {
disk := make(map[string]string) disk := make(map[string]string)
@ -265,14 +261,19 @@ func DirPath(c *gin.Context) {
if v, ok := disk[info[i].Path]; ok { if v, ok := disk[info[i].Path]; ok {
info[i].Type = v info[i].Type = v
} }
if _, ok := sharesMap[info[i].Path]; ok { }
ex := make(map[string]string) }
ex["shared"] = "true" for i := 0; i < len(info); i++ {
if v, ok := sharesMap[info[i].Path]; ok {
ex := make(map[string]interface{})
shareEx := make(map[string]string)
shareEx["shared"] = "true"
shareEx["id"] = v
ex["share"] = shareEx
info[i].Extensions = ex info[i].Extensions = ex
} }
} }
}
//Hide the files or folders in operation //Hide the files or folders in operation
fileQueue := make(map[string]string) fileQueue := make(map[string]string)
if len(service.OpStrArr) > 0 { if len(service.OpStrArr) > 0 {

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.com * @Author: LinkLeong link@icewhale.com
* @Date: 2022-07-26 11:08:48 * @Date: 2022-07-26 11:08:48
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-28 11:51:03 * @LastEditTime: 2022-08-05 12:16:39
* @FilePath: /CasaOS/route/v1/samba.go * @FilePath: /CasaOS/route/v1/samba.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -12,6 +12,7 @@ package v1
import ( import (
"fmt" "fmt"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -108,10 +109,9 @@ func GetSambaConnectionsList(c *gin.Context) {
connectionList = append(connectionList, model.Connections{ connectionList = append(connectionList, model.Connections{
ID: v.ID, ID: v.ID,
Username: v.Username, Username: v.Username,
MountPoint: v.MountPoint,
Directory: v.Directory,
Port: v.Port, Port: v.Port,
Host: v.Host, Host: v.Host,
MountPoint: v.MountPoint,
}) })
} }
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList}) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
@ -119,29 +119,24 @@ func GetSambaConnectionsList(c *gin.Context) {
func PostSambaConnectionsCreate(c *gin.Context) { func PostSambaConnectionsCreate(c *gin.Context) {
connection := model.Connections{} connection := model.Connections{}
err := c.ShouldBindJSON(&connection) c.ShouldBindJSON(&connection)
fmt.Println(err)
if connection.Port == "" { if connection.Port == "" {
connection.Port = "445" connection.Port = "445"
} }
if connection.Username == "" || connection.Directory == "" || connection.Host == "" || connection.MountPoint == "" { if connection.Username == "" || connection.Host == "" {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
return return
} }
// check is exists // check is exists
connections := service.MyService.Connections().GetConnectionByDirectory(connection.Directory) connections := service.MyService.Connections().GetConnectionByHost(connection.Host)
if len(connections) > 0 { if len(connections) > 0 {
for _, v := range connections {
if v.Host == connection.Host {
c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)}) c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)})
return return
} }
}
}
// check connect is ok // check connect is ok
if err := samba.ConnectSambaService(connection.Host, connection.Port, connection.Username, connection.Password, connection.Directory); err != nil { directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
fmt.Println("check", err) 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()}) 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 return
} }
@ -149,13 +144,21 @@ func PostSambaConnectionsCreate(c *gin.Context) {
connectionDBModel := model2.ConnectionsDBModel{} connectionDBModel := model2.ConnectionsDBModel{}
connectionDBModel.Username = connection.Username connectionDBModel.Username = connection.Username
connectionDBModel.Password = connection.Password connectionDBModel.Password = connection.Password
connectionDBModel.Directory = connection.Directory
connectionDBModel.Host = connection.Host connectionDBModel.Host = connection.Host
connectionDBModel.Port = connection.Port connectionDBModel.Port = connection.Port
connectionDBModel.MountPoint = connection.MountPoint connectionDBModel.Directories = strings.Join(directories, ",")
file.IsNotExistMkDir(connection.MountPoint) baseHostPath := "/mnt/" + connection.Host
connectionDBModel.MountPoint = baseHostPath
connection.MountPoint = baseHostPath
file.IsNotExistMkDir(baseHostPath)
for _, v := range directories {
mountPoint := baseHostPath + "/" + v
file.IsNotExistMkDir(mountPoint)
service.MyService.Connections().MountSmaba(connectionDBModel.Username, connectionDBModel.Host, v, connectionDBModel.Port, mountPoint, connectionDBModel.Password)
}
service.MyService.Connections().CreateConnection(&connectionDBModel) service.MyService.Connections().CreateConnection(&connectionDBModel)
service.MyService.Connections().MountSmaba(&connectionDBModel)
connection.ID = connectionDBModel.ID connection.ID = connectionDBModel.ID
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection}) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection})
} }
@ -167,7 +170,11 @@ func DeleteSambaConnections(c *gin.Context) {
c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)}) c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)})
return return
} }
service.MyService.Connections().UnmountSmaba(connection.MountPoint) mountPointList := service.MyService.System().GetDirPath(connection.MountPoint)
for _, v := range mountPointList {
service.MyService.Connections().UnmountSmaba(v.Path)
}
os.RemoveAll(connection.MountPoint)
service.MyService.Connections().DeleteConnection(id) service.MyService.Connections().DeleteConnection(id)
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
} }

73
route/v1/samba_test.go Normal file
View File

@ -0,0 +1,73 @@
/*
* @Author: LinkLeong link@icewhale.org
* @Date: 2022-08-02 15:10:56
* @LastEditors: LinkLeong
* @LastEditTime: 2022-08-02 16:58:42
* @FilePath: /CasaOS/route/v1/samba_test.go
* @Description:
* @Website: https://www.casaos.io
* Copyright (c) 2022 by icewhale, All Rights Reserved.
*/
package v1
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
req, _ := http.NewRequest(method, path, nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
return w
}
// func TestHelloWorld(t *testing.T) {
// // Build our expected body
// body := gin.H{
// "hello": "world",
// }
// // Grab our router
// router := "SetupRouter()"
// // Perform a GET request with that handler.
// w := performRequest(router, "GET", "/")
// // Assert we encoded correctly,
// // the request gives a 200
// assert.Equal(t, http.StatusOK, w.Code)
// // Convert the JSON response to a map
// var response map[string]string
// err := json.Unmarshal([]byte(w.Body.String()), &response)
// // Grab the value & whether or not it exists
// value, exists := response["hello"]
// // Make some assertions on the correctness of the response.
// assert.Nil(t, err)
// assert.True(t, exists)
// assert.Equal(t, body["hello"], value)
// }
func TestGetSambaSharesList(t *testing.T) {
gin.SetMode(gin.TestMode)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
executeWithContext := func() *httptest.ResponseRecorder {
response := httptest.NewRecorder()
con, ginEngine := gin.CreateTestContext(response)
requestUrl := "/v1/samba/shares"
httpRequest, _ := http.NewRequest("GET", requestUrl, nil)
GetSambaSharesList(con)
ginEngine.ServeHTTP(response, httpRequest)
return response
}
t.Run("Happy", func(t *testing.T) {
res := executeWithContext()
assert.Equal(t, http.StatusOK, res.Code)
})
}

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.com * @Author: LinkLeong link@icewhale.com
* @Date: 2022-07-11 16:02:29 * @Date: 2022-07-11 16:02:29
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-29 14:14:17 * @LastEditTime: 2022-08-04 11:27:25
* @FilePath: /CasaOS/route/v1/storage.go * @FilePath: /CasaOS/route/v1/storage.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -13,7 +13,6 @@ package v1
import ( import (
"reflect" "reflect"
"strconv" "strconv"
"strings"
"github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
@ -22,14 +21,22 @@ import (
) )
func GetStorageList(c *gin.Context) { func GetStorageList(c *gin.Context) {
system := c.Query("system")
storages := []model.Storages{} storages := []model.Storages{}
disks := service.MyService.Disk().LSBLK(false) disks := service.MyService.Disk().LSBLK(false)
diskNumber := 1 diskNumber := 1
children := 1 children := 1
findSystem := 0
for _, d := range disks { for _, d := range disks {
if d.Tran != "usb" {
tempSystemDisk := false
children = 1 children = 1
if d.Tran == "sata" || d.Tran == "nvme" || d.Tran == "spi" || d.Tran == "sas" || strings.Contains(d.SubSystems, "virtio") || (d.Tran == "ata" && d.Type == "disk") { tempDisk := model.Storages{
DiskName: d.Model,
Path: d.Path,
Size: d.Size,
}
storageArr := []model.Storage{} storageArr := []model.Storage{}
temp := service.MyService.Disk().SmartCTL(d.Path) temp := service.MyService.Disk().SmartCTL(d.Path)
if reflect.DeepEqual(temp, model.SmartctlA{}) { if reflect.DeepEqual(temp, model.SmartctlA{}) {
@ -37,6 +44,24 @@ func GetStorageList(c *gin.Context) {
} }
for _, v := range d.Children { for _, v := range d.Children {
if v.MountPoint != "" { 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 := model.Storage{}
stor.MountPoint = v.MountPoint stor.MountPoint = v.MountPoint
stor.Size = v.FSSize stor.Size = v.FSSize
@ -53,16 +78,27 @@ func GetStorageList(c *gin.Context) {
storageArr = append(storageArr, stor) storageArr = append(storageArr, stor)
} }
} }
if len(storageArr) > 0 { if len(storageArr) > 0 {
storages = append(storages, model.Storages{ if tempSystemDisk && len(system) > 0 {
DiskName: d.Model, tempStorageArr := []model.Storage{}
Path: d.Path, for i := 0; i < len(storageArr); i++ {
Size: d.Size, if storageArr[i].MountPoint != "/boot/efi" && storageArr[i].Type != "swap" {
Children: storageArr, 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 diskNumber += 1
} }
} }
} }
}
c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storages}) c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: storages})
} }

View File

@ -354,21 +354,13 @@ func GetSystemUtilization(c *gin.Context) {
temp.Model = v.Model temp.Model = v.Model
temp.Name = v.Name temp.Name = v.Name
temp.Size = v.Size temp.Size = v.Size
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children { for _, child := range v.Children {
if len(child.MountPoint) > 0 { if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64) avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail temp.Avail += avail
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
temp.Used += used
} else {
mountTemp = false
} }
} }
temp.Mount = mountTemp
usb = append(usb, temp) usb = append(usb, temp)
} }
} }

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.org * @Author: LinkLeong link@icewhale.org
* @Date: 2022-07-26 18:13:22 * @Date: 2022-07-26 18:13:22
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-27 13:44:12 * @LastEditTime: 2022-08-04 20:10:31
* @FilePath: /CasaOS/service/connections.go * @FilePath: /CasaOS/service/connections.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -20,11 +20,12 @@ import (
type ConnectionsService interface { type ConnectionsService interface {
GetConnectionsList() (connections []model2.ConnectionsDBModel) GetConnectionsList() (connections []model2.ConnectionsDBModel)
GetConnectionByDirectory(directory string) (connections []model2.ConnectionsDBModel) GetConnectionByHost(host string) (connections []model2.ConnectionsDBModel)
GetConnectionByID(id string) (connections model2.ConnectionsDBModel) GetConnectionByID(id string) (connections model2.ConnectionsDBModel)
CreateConnection(connection *model2.ConnectionsDBModel) CreateConnection(connection *model2.ConnectionsDBModel)
DeleteConnection(id string) DeleteConnection(id string)
MountSmaba(connection *model2.ConnectionsDBModel) string UpdateConnection(connection *model2.ConnectionsDBModel)
MountSmaba(username, host, directory, port, mountPoint, password string) string
UnmountSmaba(mountPoint string) string UnmountSmaba(mountPoint string) string
} }
@ -32,27 +33,30 @@ type connectionsStruct struct {
db *gorm.DB db *gorm.DB
} }
func (s *connectionsStruct) GetConnectionByDirectory(directory string) (connections []model2.ConnectionsDBModel) { func (s *connectionsStruct) GetConnectionByHost(host string) (connections []model2.ConnectionsDBModel) {
s.db.Select("username,host,directory,status,mount_point,id").Where("directory = ?", directory).Find(&connections) s.db.Select("username,host,status,id").Where("host = ?", host).Find(&connections)
return return
} }
func (s *connectionsStruct) GetConnectionByID(id string) (connections model2.ConnectionsDBModel) { func (s *connectionsStruct) GetConnectionByID(id string) (connections model2.ConnectionsDBModel) {
s.db.Select("username,password,host,directory,status,mount_point,id").Where("id = ?", id).First(&connections) s.db.Select("username,password,host,status,id,directories,mount_point,port").Where("id = ?", id).First(&connections)
return return
} }
func (s *connectionsStruct) GetConnectionsList() (connections []model2.ConnectionsDBModel) { func (s *connectionsStruct) GetConnectionsList() (connections []model2.ConnectionsDBModel) {
s.db.Select("username,host,port,directory,status,mount_point,id").Find(&connections) s.db.Select("username,host,port,status,id,mount_point").Find(&connections)
return return
} }
func (s *connectionsStruct) CreateConnection(connection *model2.ConnectionsDBModel) { func (s *connectionsStruct) CreateConnection(connection *model2.ConnectionsDBModel) {
s.db.Create(connection) s.db.Create(connection)
} }
func (s *connectionsStruct) UpdateConnection(connection *model2.ConnectionsDBModel) {
s.db.Save(connection)
}
func (s *connectionsStruct) DeleteConnection(id string) { func (s *connectionsStruct) DeleteConnection(id string) {
s.db.Where("id= ?", id).Delete(&model.ConnectionsDBModel{}) s.db.Where("id= ?", id).Delete(&model.ConnectionsDBModel{})
} }
func (s *connectionsStruct) MountSmaba(connection *model2.ConnectionsDBModel) string { func (s *connectionsStruct) MountSmaba(username, host, directory, port, mountPoint, password string) string {
str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;MountCIFS " + connection.Username + " " + connection.Host + " " + connection.Directory + " " + connection.Port + " " + connection.MountPoint + " " + connection.Password) str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;MountCIFS " + username + " " + host + " " + directory + " " + port + " " + mountPoint + " " + password)
return str return str
} }
func (s *connectionsStruct) UnmountSmaba(mountPoint string) string { func (s *connectionsStruct) UnmountSmaba(mountPoint string) string {

View File

@ -36,6 +36,7 @@ type DiskService interface {
DeleteMount(id string) DeleteMount(id string)
UpdateMountPoint(m model2.SerialDisk) UpdateMountPoint(m model2.SerialDisk)
RemoveLSBLKCache() RemoveLSBLKCache()
UmountUSB(path string)
} }
type diskService struct { type diskService struct {
db *gorm.DB db *gorm.DB
@ -45,6 +46,10 @@ func (d *diskService) RemoveLSBLKCache() {
key := "system_lsblk" key := "system_lsblk"
Cache.Delete(key) 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 { func (d *diskService) SmartCTL(path string) model.SmartctlA {
key := "system_smart_" + path key := "system_smart_" + path
@ -243,9 +248,9 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
} }
func (d *diskService) MountDisk(path, volume string) { func (d *diskService) MountDisk(path, volume string) {
fmt.Println("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume) //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) r := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;do_mount " + path + " " + volume)
fmt.Print(r) fmt.Println(r)
} }
func (d *diskService) SaveMountPoint(m model2.SerialDisk) { func (d *diskService) SaveMountPoint(m model2.SerialDisk) {

View File

@ -45,7 +45,7 @@ import (
type DockerService interface { type DockerService interface {
DockerPullImage(imageName string, icon, name string) error DockerPullImage(imageName string, icon, name string) error
IsExistImage(imageName string) bool IsExistImage(imageName string) bool
DockerContainerCreate(imageName string, m model.CustomizationPostData) (containerId string, err error) DockerContainerCreate(m model.CustomizationPostData, id string) (containerId string, err error)
DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error) DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error)
DockerContainerStart(name string) error DockerContainerStart(name string) error
DockerContainerStats(name string) (string, error) DockerContainerStats(name string) (string, error)
@ -376,7 +376,7 @@ func (ds *dockerService) DockerContainerCopyCreate(info *types.ContainerJSON) (c
//param mapPort 容器主端口映射到外部的端口 //param mapPort 容器主端口映射到外部的端口
//param tcp 容器其他tcp端口 //param tcp 容器其他tcp端口
//param udp 容器其他udp端口 //param udp 容器其他udp端口
func (ds *dockerService) DockerContainerCreate(imageName string, m model.CustomizationPostData) (containerId string, err error) { func (ds *dockerService) DockerContainerCreate(m model.CustomizationPostData, id string) (containerId string, err error) {
if len(m.NetworkModel) == 0 { if len(m.NetworkModel) == 0 {
m.NetworkModel = "bridge" m.NetworkModel = "bridge"
} }
@ -385,6 +385,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
if err != nil { if err != nil {
return "", err return "", err
} }
defer cli.Close() defer cli.Close()
ports := make(nat.PortSet) ports := make(nat.PortSet)
portMaps := make(nat.PortMap) portMaps := make(nat.PortMap)
@ -523,15 +524,26 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
if len(m.HostName) == 0 { if len(m.HostName) == 0 {
m.HostName = m.Label m.HostName = m.Label
} }
config := &container.Config{
Image: imageName, info, err := cli.ContainerInspect(context.Background(), id)
Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin, "casaos": "casaos"}, hostConfig := &container.HostConfig{}
Env: envArr, config := &container.Config{}
// Healthcheck: health, config.Labels = map[string]string{}
Hostname: m.HostName, if err == nil {
Cmd: m.Cmd, // info.HostConfig = &container.HostConfig{}
// info.Config = &container.Config{}
// info.NetworkSettings = &types.NetworkSettings{}
hostConfig = info.HostConfig
config = info.Config
} }
config.Cmd = m.Cmd
config.Image = m.Image
config.Env = envArr
config.Hostname = m.HostName
config.ExposedPorts = ports
config.Labels["origin"] = m.Origin
config.Labels["casaos"] = "casaos"
config.Labels["web"] = m.PortMap config.Labels["web"] = m.PortMap
config.Labels["icon"] = m.Icon config.Labels["icon"] = m.Icon
config.Labels["desc"] = m.Description config.Labels["desc"] = m.Description
@ -541,12 +553,19 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
config.Labels["protocol"] = m.Protocol config.Labels["protocol"] = m.Protocol
config.Labels["host"] = m.Host config.Labels["host"] = m.Host
config.Labels["name"] = m.Label config.Labels["name"] = m.Label
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(m.NetworkModel), Privileged: m.Privileged, CapAdd: m.CapAdd} //container, err := cli.ContainerCreate(context.Background(), info.Config, info.HostConfig, &network.NetworkingConfig{info.NetworkSettings.Networks}, nil, info.Name)
hostConfig.Mounts = volumes
hostConfig.Privileged = m.Privileged
hostConfig.CapAdd = m.CapAdd
hostConfig.NetworkMode = container.NetworkMode(m.NetworkModel)
hostConfig.RestartPolicy = rp
hostConfig.Resources = res
//hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: , Privileged: m.Privileged, CapAdd: m.CapAdd}
//if net != "host" { //if net != "host" {
config.ExposedPorts = ports
hostConfig.PortBindings = portMaps hostConfig.PortBindings = portMaps
//} //}
containerDb, err := cli.ContainerCreate(context.Background(), containerDb, err := cli.ContainerCreate(context.Background(),
config, config,
hostConfig, hostConfig,

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.org * @Author: LinkLeong link@icewhale.org
* @Date: 2022-07-26 17:17:57 * @Date: 2022-07-26 17:17:57
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-27 10:44:46 * @LastEditTime: 2022-08-01 17:08:08
* @FilePath: /CasaOS/service/model/o_connections.go * @FilePath: /CasaOS/service/model/o_connections.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -18,9 +18,9 @@ type ConnectionsDBModel struct {
Password string `json:"password"` Password string `json:"password"`
Host string `json:"host"` Host string `json:"host"`
Port string `json:"port"` Port string `json:"port"`
Directory string `json:"directory"`
MountPoint string `json:"mount_point"`
Status string `json:"status"` Status string `json:"status"`
Directories string `json:"directories"` // string array
MountPoint string `json:"mount_point"` //parent directory of mount point
} }
func (p *ConnectionsDBModel) TableName() string { func (p *ConnectionsDBModel) TableName() string {

View File

@ -383,5 +383,7 @@ CheckServiceStatus(){
echo "running" echo "running"
fi fi
} }
UDEVILUmount(){
$sudo_cmd udevil umount -f $1
}

View File

@ -2,7 +2,7 @@
* @Author: LinkLeong link@icewhale.com * @Author: LinkLeong link@icewhale.com
* @Date: 2022-02-17 18:53:22 * @Date: 2022-02-17 18:53:22
* @LastEditors: LinkLeong * @LastEditors: LinkLeong
* @LastEditTime: 2022-07-18 18:47:15 * @LastEditTime: 2022-08-10 13:50:57
* @FilePath: /CasaOS/types/system.go * @FilePath: /CasaOS/types/system.go
* @Description: * @Description:
* @Website: https://www.casaos.io * @Website: https://www.casaos.io
@ -10,6 +10,6 @@
*/ */
package types package types
const CURRENTVERSION = "0.3.4" const CURRENTVERSION = "0.3.5"
const BODY = " " const BODY = " "

View File

@ -20,7 +20,7 @@
<title> <title>
CasaOS CasaOS
</title> </title>
<link href="/ui/css/13.a16d5119.css" rel="prefetch"><link href="/ui/css/14.cf8c898a.css" rel="prefetch"><link href="/ui/css/4.f7a3b3b4.css" rel="prefetch"><link href="/ui/css/5.e8438f80.css" rel="prefetch"><link href="/ui/css/6.d72d6157.css" rel="prefetch"><link href="/ui/css/7.805596b0.css" rel="prefetch"><link href="/ui/css/8.92188e4d.css" rel="prefetch"><link href="/ui/css/9.dccf29b4.css" rel="prefetch"><link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/10.js" rel="prefetch"><link href="/ui/js/11.js" rel="prefetch"><link href="/ui/js/12.js" rel="prefetch"><link href="/ui/js/13.js" rel="prefetch"><link href="/ui/js/14.js" rel="prefetch"><link href="/ui/js/15.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/8.js" rel="prefetch"><link href="/ui/js/9.js" rel="prefetch"><link href="/ui/css/app.344b6034.css" rel="preload" as="style"><link href="/ui/css/vendors~app.c42f9a2b.css" rel="preload" as="style"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/vendors~app.js" rel="preload" as="script"><link href="/ui/css/vendors~app.c42f9a2b.css" rel="stylesheet"><link href="/ui/css/app.344b6034.css" rel="stylesheet"></head> <link href="/ui/css/13.a16d5119.css" rel="prefetch"><link href="/ui/css/14.cf8c898a.css" rel="prefetch"><link href="/ui/css/4.f17f9b01.css" rel="prefetch"><link href="/ui/css/5.e8438f80.css" rel="prefetch"><link href="/ui/css/6.d72d6157.css" rel="prefetch"><link href="/ui/css/7.805596b0.css" rel="prefetch"><link href="/ui/css/8.92188e4d.css" rel="prefetch"><link href="/ui/css/9.dccf29b4.css" rel="prefetch"><link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/10.js" rel="prefetch"><link href="/ui/js/11.js" rel="prefetch"><link href="/ui/js/12.js" rel="prefetch"><link href="/ui/js/13.js" rel="prefetch"><link href="/ui/js/14.js" rel="prefetch"><link href="/ui/js/15.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/8.js" rel="prefetch"><link href="/ui/js/9.js" rel="prefetch"><link href="/ui/css/app.c78d232d.css" rel="preload" as="style"><link href="/ui/css/vendors~app.c42f9a2b.css" rel="preload" as="style"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/vendors~app.js" rel="preload" as="script"><link href="/ui/css/vendors~app.c42f9a2b.css" rel="stylesheet"><link href="/ui/css/app.c78d232d.css" rel="stylesheet"></head>
<body> <body>
<noscript> <noscript>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long