Compare commits

...

25 Commits

Author SHA1 Message Date
link
63c6c2cebb Merge pull request #111 from IceWhaleTech/dev
Delete CasaOS-linux-amd64
2022-02-17 19:22:14 +08:00
link
6cba025679 Delete CasaOS-linux-amd64 2022-02-17 19:21:19 +08:00
link
d25b93c972 Merge pull request #110 from IceWhaleTech/dev
Dev
2022-02-17 18:53:54 +08:00
link
b14861703c Merge branch 'dev' of ssh://github.com/IceWhaleTech/CasaOS into dev 2022-02-17 18:53:29 +08:00
link
32604225ce update ui 2022-02-17 18:52:14 +08:00
link
f623b29c38 Merge pull request #109 from IceWhaleTech/dev
Dev
2022-02-17 18:47:44 +08:00
link
94ae6ee8ec Merge branch 'main' into dev 2022-02-17 18:47:36 +08:00
link
5115bf72e1 update desc 2022-02-17 18:44:51 +08:00
link
e1a928cd78 Fixed issues 2022-02-17 18:43:25 +08:00
link
3977519c43 Update assist.sh 2022-01-30 11:21:24 +08:00
link
2f87834ac9 Merge pull request #93 from IceWhaleTech/dev
Update route.go
2022-01-28 16:25:01 +08:00
link
53335012d8 Update route.go 2022-01-28 16:24:28 +08:00
link
9d6302f7e3 Merge pull request #92 from IceWhaleTech/dev
Update UI
2022-01-28 16:14:59 +08:00
link
20950e2a60 Update UI 2022-01-28 16:14:35 +08:00
link
0e0e507f8f Merge pull request #91 from IceWhaleTech/dev
update ui
2022-01-28 15:35:15 +08:00
link
46e14617b6 update ui 2022-01-28 15:34:32 +08:00
link
903c73fafb Merge pull request #90 from IceWhaleTech/dev
update web
2022-01-28 14:33:40 +08:00
link
42a56df4a5 update web 2022-01-28 14:32:49 +08:00
link
493dc5c032 Merge pull request #89 from IceWhaleTech/dev
Compatible with more types of disks
2022-01-28 14:06:58 +08:00
link
9a73bc2a18 Compatible with more types of disks
Add usb display
2022-01-28 14:06:27 +08:00
link
55a9acd9f6 Merge pull request #85 from IceWhaleTech/dev
Apply multilingual support
2022-01-26 18:51:14 +08:00
link
d060968b7a Apply multilingual support 2022-01-26 18:50:34 +08:00
link
88a7f53130 Merge pull request #82 from IceWhaleTech/dev
Dev
2022-01-26 11:33:33 +08:00
link
26e5b18a5d Merge branch 'dev' of ssh://github.com/IceWhaleTech/CasaOS into dev 2022-01-26 11:33:02 +08:00
link
011ace96f6 update ui 2022-01-26 11:32:57 +08:00
49 changed files with 3120 additions and 427 deletions

2
UI

Submodule UI updated: 8146d1f4cb...106902c76a

View File

@@ -15,6 +15,9 @@ ProjectPath = /casaOS/server
HttpPort = 8089
RunMode = release
ServerApi = https://api.casaos.zimaboard.com
Handshake =
Token =
[user]
UserName = admin
@@ -22,7 +25,6 @@ PWD = zimaboard
Email = user@gmail.com
Description = description
Initialized = false
Token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVyZXJlIiwicGFzc3dvcmQiOiJhZHNmZGYiLCJleHAiOjE2MjQwMDU0ODEsImlzcyI6Imdpbi1ibG9nIn0.JNsCccZuFCwlSMLJg62iOIB2xymk_k7xGa11xhZ07bc
[zerotier]
UserName = user

10
go.mod
View File

@@ -10,10 +10,11 @@ require (
github.com/bits-and-blooms/bitset v1.2.1 // indirect
github.com/containerd/containerd v1.5.7
github.com/containerd/continuity v0.2.0 // indirect
github.com/docker/distribution v2.8.0+incompatible // indirect
github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
github.com/gin-contrib/gzip v0.0.2 // indirect
github.com/gin-contrib/gzip v0.0.2
github.com/gin-gonic/gin v1.7.2
github.com/go-ini/ini v1.62.0
github.com/go-ole/go-ole v1.2.5 // indirect
@@ -33,8 +34,10 @@ require (
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-sqlite3 v1.14.11 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/selinux v1.8.5 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1
@@ -49,7 +52,6 @@ require (
github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.3
github.com/tidwall/gjson v1.10.2
github.com/tidwall/sjson v1.2.3
github.com/tklauser/go-sysconf v0.3.6 // indirect
github.com/ugorji/go v1.2.6 // indirect
go.opencensus.io v0.23.0 // indirect
@@ -67,6 +69,6 @@ require (
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gorm.io/driver/sqlite v1.1.5
gorm.io/gorm v1.21.15
gorm.io/driver/sqlite v1.2.6
gorm.io/gorm v1.22.5
)

16
go.sum
View File

@@ -261,6 +261,8 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY=
github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -492,6 +494,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
@@ -553,6 +557,9 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.11 h1:gt+cp9c0XGqe9S/wAHTL3n/7MqY+siPWgWJgqdsFrzQ=
github.com/mattn/go-sqlite3 v1.14.11/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
@@ -608,6 +615,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -747,8 +756,6 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
@@ -1225,8 +1232,13 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.1.5 h1:JU8G59VyKu1x1RMQgjefQnkZjDe9wHc1kARDZPu5dZs=
gorm.io/driver/sqlite v1.1.5/go.mod h1:NpaYMcVKEh6vLJ47VP6T7Weieu4H1Drs3dGD/K6GrGc=
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk=
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU=
gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=

View File

@@ -58,8 +58,9 @@ func main() {
r := route.InitRouter()
//service.SyncTask(sqliteDB)
cron2 := cron.New() //创建一个cron实例
//执行定时任务每5秒执行一次
err := cron2.AddFunc("0 0 0 1/1 * *", func() {
//every day execution
err := cron2.AddFunc("0 0/1 * * * *", func() {
//service.PushIpInfo(*&config.ServerInfo.Token)
//service.UpdataDDNSList(mysqldb)
//service.SyncTask(sqliteDB)
})
@@ -77,6 +78,7 @@ func main() {
WriteTimeout: 60 * time.Second,
MaxHeaderBytes: 1 << 20,
}
s.ListenAndServe()
}

View File

@@ -39,6 +39,10 @@ type ServerAppList struct {
Origin string `json:"origin"`
Type int `json:"type"`
Developer string `json:"developer"`
HostName string `json:"host_name"`
Privileged bool `json:"privileged"`
CapAdd Strings `json:"cap_add"`
Cmd Strings `json:"cmd"`
}
type Ports struct {

View File

@@ -20,6 +20,7 @@ type LSBLKModel struct {
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"`
@@ -47,6 +48,15 @@ type Drive struct {
Path string `json:"path"`
}
type DriveUSB struct {
Name string `json:"name"`
Size uint64 `json:"size"`
Used uint64 `json:"use"`
Model string `json:"model"`
Mount bool `json:"mount"` //是否完全挂载
Avail uint64 `json:"avail"` //可用空间
}
type Storage struct {
Name string `json:"name"`
MountPoint string `json:"mountpoint"`

6
model/heart.go Normal file
View File

@@ -0,0 +1,6 @@
package model
type CasaOSHeart struct {
UuId string `json:"uuid"`
Type string `json:"type"`
}

View File

@@ -114,12 +114,16 @@ type CustomizationPostData struct {
Volumes PathArray `json:"volumes"`
Devices PathArray `json:"devices"`
//Port string `json:"port,omitempty"`
PortMap string `json:"port_map"`
CpuShares int64 `json:"cpu_shares"`
Memory int64 `json:"memory"`
Restart string `json:"restart"`
EnableUPNP bool `json:"enable_upnp"`
Label string `json:"label"`
Description string `json:"description"`
Position bool `json:"position"`
PortMap string `json:"port_map"`
CpuShares int64 `json:"cpu_shares"`
Memory int64 `json:"memory"`
Restart string `json:"restart"`
EnableUPNP bool `json:"enable_upnp"`
Label string `json:"label"`
Description string `json:"description"`
Position bool `json:"position"`
HostName string `json:"host_name"`
Privileged bool `json:"privileged"`
CapAdd []string `json:"cap_add"`
Cmd []string `json:"cmd"`
}

6
model/notify.go Normal file
View File

@@ -0,0 +1,6 @@
package model
type NotifyMssage struct {
Type string `json:"type"`
Data string `json:"data"`
}

19
model/person.go Normal file
View File

@@ -0,0 +1,19 @@
package model
import "time"
type PersionModel struct {
Token string `json:"token"`
Ips []string `json:"ips"`
CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
}
//记录链接状态
type ConnectState struct {
From string `json:"from"`
To string `json:"to"`
Type string `json:"type"` //current state 1:ready 2:ok
CreatedAt time.Time `json:"created_at"`
UUId string `json:"uuid"` //对接标识
}

View File

@@ -24,6 +24,8 @@ type ServerModel struct {
RunMode string
ServerApi string
LockAccount bool
Handshake string
Token string
}
//服务配置

View File

@@ -101,7 +101,6 @@ func ExecSmartCTLByPath(path string) []byte {
output, err := exec.CommandContext(ctx, "smartctl", "-a", path, "-j").Output()
if err != nil {
fmt.Println("smartctl", err)
fmt.Println("output", string(output))
return nil
}
return output

View File

@@ -2,6 +2,7 @@ package file
import (
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"os"
@@ -159,3 +160,68 @@ func ReadFullFile(path string) []byte {
}
return content
}
// File copies a single file from src to dst
func CopyFile(src, dst string) error {
var err error
var srcfd *os.File
var dstfd *os.File
var srcinfo os.FileInfo
if srcfd, err = os.Open(src); err != nil {
return err
}
defer srcfd.Close()
if dstfd, err = os.Create(dst); err != nil {
return err
}
defer dstfd.Close()
if _, err = io.Copy(dstfd, srcfd); err != nil {
return err
}
if srcinfo, err = os.Stat(src); err != nil {
return err
}
return os.Chmod(dst, srcinfo.Mode())
}
// Dir copies a whole directory recursively
func CopyDir(src string, dst string) error {
var err error
var fds []os.FileInfo
var srcinfo os.FileInfo
if srcinfo, err = os.Stat(src); err != nil {
return err
}
if !srcinfo.IsDir() {
if err = CopyFile(src, dst); err != nil {
fmt.Println(err)
}
return nil
}
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
return err
}
if fds, err = ioutil.ReadDir(src); err != nil {
return err
}
for _, fd := range fds {
srcfp := path.Join(src, fd.Name())
dstfp := path.Join(dst, fd.Name())
if fd.IsDir() {
if err = CopyDir(srcfp, dstfp); err != nil {
fmt.Println(err)
}
} else {
if err = CopyFile(srcfp, dstfp); err != nil {
fmt.Println(err)
}
}
}
return nil
}

View File

@@ -36,6 +36,7 @@ const (
//file
FILE_DOES_NOT_EXIST = 60001
FILE_READ_ERROR = 60002
FILE_DELETE_ERROR = 60003
//shortcuts
SHORTCUTS_URL_ERROR = 70001
@@ -78,6 +79,7 @@ var MsgFlags = map[int]string{
FILE_DOES_NOT_EXIST: "File does not exist",
FILE_READ_ERROR: "File read error",
FILE_DELETE_ERROR: "Delete error",
SHORTCUTS_URL_ERROR: "URL error",
}

View File

@@ -25,6 +25,8 @@ func InitFunction() {
Update2_3()
CheckSerialDiskMount()
CheckToken2_9()
}
var syncIsExistence = false
@@ -35,7 +37,7 @@ func installSyncthing(appId string) {
m := model.CustomizationPostData{}
var dockerImage string
var dockerImageVersion string
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system")
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "system", "us_en")
dockerImage = appInfo.Image
dockerImageVersion = appInfo.ImageVersion
@@ -195,18 +197,18 @@ func CheckSerialDiskMount() {
// check mount point
dbList := service.MyService.Disk().GetSerialAll()
list := service.MyService.Disk().LSBLK()
list := service.MyService.Disk().LSBLK(true)
mountPoint := make(map[string]string, len(dbList))
//remount
for _, v := range dbList {
mountPoint[v.Path] = v.MountPoint
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.Path]; ok {
if m, ok := mountPoint[h.UUID]; ok {
//mount point check
volume := m
if !file.CheckNotExist(m) {
@@ -217,7 +219,8 @@ func CheckSerialDiskMount() {
service.MyService.Disk().MountDisk(h.Path, volume)
if volume != m {
ms := model2.SerialDisk{}
ms.Serial = v.Serial
ms.UUID = v.UUID
ms.MountPoint = volume
service.MyService.Disk().UpdateMountPoint(ms)
}
@@ -233,3 +236,11 @@ func CheckSerialDiskMount() {
func Update2_3() {
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
}
func CheckToken2_9() {
if len(config.ServerInfo.Token) == 0 {
token := uuid.NewV4().String
config.ServerInfo.Token = token()
config.Cfg.Section("server").Key("Token").SetValue(token())
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
}

View File

@@ -8,6 +8,7 @@ import (
jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt"
v1 "github.com/IceWhaleTech/CasaOS/route/v1"
"github.com/IceWhaleTech/CasaOS/web"
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
)
@@ -18,6 +19,7 @@ func InitRouter() *gin.Engine {
r := gin.Default()
r.Use(middleware.Cors())
r.Use(gzip.Gzip(gzip.DefaultCompression))
gin.SetMode(config.ServerInfo.RunMode)
r.StaticFS("/ui", http.FS(web.Static))
@@ -205,13 +207,14 @@ func InitRouter() *gin.Engine {
v1FileGroup.PUT("/rename", v1.RenamePath)
v1FileGroup.GET("/read", v1.GetFilerContent)
v1FileGroup.POST("/upload", v1.PostFileUpload)
v1FileGroup.GET("/catalog", v1.DirPath)
//创建目录
v1FileGroup.GET("/dirpath", v1.DirPath)
//create folder
v1FileGroup.POST("/mkdir", v1.MkdirAll)
v1FileGroup.POST("/create", v1.PostCreateFile)
v1FileGroup.GET("/download", v1.GetDownloadFile)
v1FileGroup.PUT("/move", v1.PutFileMove)
v1FileGroup.POST("/operate", v1.PostOperateFileOrDir)
v1FileGroup.DELETE("delete", v1.DeleteFile)
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
}
v1DiskGroup := v1Group.Group("/disk")
@@ -241,6 +244,7 @@ func InitRouter() *gin.Engine {
//删除分区
v1DiskGroup.DELETE("/delpart", v1.RemovePartition)
v1DiskGroup.GET("/usb", v1.GetUSBList)
}
v1ShareGroup := v1Group.Group("/share")
@@ -280,6 +284,11 @@ func InitRouter() *gin.Engine {
{
v1SearchGroup.GET("/search", v1.GetSearchList)
}
v1PersonGroup := v1Group.Group("/persion")
v1PersonGroup.Use()
{
v1PersonGroup.GET("/test", v1.PersonTest)
}
v1Group.GET("/sync/config", v1.GetSyncConfig)
v1Group.Any("/syncthing/*url", v1.SyncToSyncthing)

View File

@@ -35,7 +35,8 @@ func AppList(c *gin.Context) {
t := c.DefaultQuery("type", "rank")
categoryId := c.DefaultQuery("category_id", "0")
key := c.DefaultQuery("key", "")
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
language := c.GetHeader("Language")
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key, language)
// for i := 0; i < len(recommend); i++ {
// ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
// if ct != nil {
@@ -137,7 +138,8 @@ func AppUsageList(c *gin.Context) {
func AppInfo(c *gin.Context) {
id := c.Param("id")
info := service.MyService.OAPI().GetServerAppInfo(id, "")
language := c.GetHeader("Language")
info := service.MyService.OAPI().GetServerAppInfo(id, "", language)
if info.NetworkModel != "host" {
for i := 0; i < len(info.Ports); i++ {
if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {

View File

@@ -1,6 +1,7 @@
package v1
import (
"fmt"
"net/http"
"reflect"
"strconv"
@@ -27,7 +28,7 @@ var diskMap = make(map[string]string)
// @Success 200 {string} string "ok"
// @Router /disk/list [get]
func GetDiskList(c *gin.Context) {
list := service.MyService.Disk().LSBLK()
list := service.MyService.Disk().LSBLK(false)
dbList := service.MyService.Disk().GetSerialAll()
part := make(map[string]int64, len(dbList))
for _, v := range dbList {
@@ -53,28 +54,56 @@ func GetDiskList(c *gin.Context) {
if len(list[i].Children) > 0 && findSystem == 0 {
for j := 0; j < len(list[i].Children); j++ {
if list[i].Children[j].MountPoint == "/" {
stor := model.Storage{}
stor.Name = "System"
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"
if len(list[i].Children[j].Children) > 0 {
for _, v := range list[i].Children[j].Children {
if v.MountPoint == "/" {
stor := model.Storage{}
stor.Name = "System"
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
disks = append(disks, disk)
storage = append(storage, stor)
findSystem = 1
break
}
}
} else {
if list[i].Children[j].MountPoint == "/" {
stor := model.Storage{}
stor.Name = "System"
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 {
@@ -82,10 +111,10 @@ func GetDiskList(c *gin.Context) {
continue
}
if list[i].Tran == "sata" {
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" {
temp := service.MyService.Disk().SmartCTL(list[i].Path)
if reflect.DeepEqual(temp, model.SmartctlA{}) {
continue
temp.SmartStatus.Passed = true
}
if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
stor := model.Storage{}
@@ -137,7 +166,7 @@ func GetDiskList(c *gin.Context) {
// @Router /disk/lists [get]
func GetPlugInDisks(c *gin.Context) {
list := service.MyService.Disk().LSBLK()
list := service.MyService.Disk().LSBLK(true)
var result []*disk.UsageStat
for _, item := range list {
result = append(result, service.MyService.Disk().GetDiskInfoByPath(item.Path))
@@ -252,13 +281,12 @@ func RemovePartition(c *gin.Context) {
func AddPartition(c *gin.Context) {
name := c.PostForm("name")
path := c.PostForm("path")
serial := c.PostForm("serial")
format, _ := strconv.ParseBool(c.PostForm("format"))
if len(name) == 0 || len(path) == 0 || len(serial) == 0 {
if len(name) == 0 || len(path) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
return
}
if _, ok := diskMap[serial]; ok {
if _, ok := diskMap[path]; ok {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_BUSYING, Message: oasis_err.GetMsg(oasis_err.DISK_BUSYING)})
return
}
@@ -267,36 +295,49 @@ func AddPartition(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.NAME_NOT_AVAILABLE, Message: oasis_err.GetMsg(oasis_err.NAME_NOT_AVAILABLE)})
return
}
diskMap[serial] = "busying"
diskMap[path] = "busying"
currentDisk := service.MyService.Disk().GetDiskInfo(path)
if !format {
if len(currentDisk.Children) != 1 || !(len(currentDisk.Children) > 0 && currentDisk.Children[0].FsType == "ext4") {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.DISK_NEEDS_FORMAT, Message: oasis_err.GetMsg(oasis_err.DISK_NEEDS_FORMAT)})
delete(diskMap, serial)
delete(diskMap, path)
return
}
} else {
service.MyService.Disk().AddPartition(path)
}
formatBool := true
for formatBool {
currentDisk = service.MyService.Disk().GetDiskInfo(path)
fmt.Println(currentDisk.Children)
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(http.StatusOK, model.Result{Success: oasis_err.DISK_NEEDS_FORMAT, Message: oasis_err.GetMsg(oasis_err.DISK_NEEDS_FORMAT)})
return
}
mountPath := "/DATA/" + name
service.MyService.Disk().MountDisk(path, mountPath)
m := model2.SerialDisk{}
m.MountPoint = mountPath
m.Path = path + "1"
m.Serial = serial
m.Path = currentDisk.Children[0].Path
m.UUID = currentDisk.Children[0].UUID
m.State = 0
m.CreatedAt = time.Now().Unix()
service.MyService.Disk().SaveMountPoint(m)
//mount dir
service.MyService.Disk().MountDisk(path+"1", mountPath)
service.MyService.Disk().MountDisk(currentDisk.Children[0].Path, mountPath)
service.MyService.Disk().RemoveLSBLKCache()
delete(diskMap, serial)
delete(diskMap, path)
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
}
@@ -334,7 +375,7 @@ func PostMountDisk(c *gin.Context) {
m := model2.SerialDisk{}
m.MountPoint = mountPath
m.Path = path
m.Serial = serial
m.UUID = serial
m.State = 0
//service.MyService.Disk().SaveMountPoint(m)
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
@@ -401,7 +442,7 @@ func DeleteDisk(c *gin.Context) {
func GetDiskCheck(c *gin.Context) {
dbList := service.MyService.Disk().GetSerialAll()
list := service.MyService.Disk().LSBLK()
list := service.MyService.Disk().LSBLK(true)
mapList := make(map[string]string)
@@ -410,7 +451,7 @@ func GetDiskCheck(c *gin.Context) {
}
for _, v := range dbList {
if _, ok := mapList[v.Serial]; !ok {
if _, ok := mapList[v.UUID]; !ok {
//disk undefind
c.JSON(http.StatusOK, model.Result{Success: oasis_err.ERROR, Message: oasis_err.GetMsg(oasis_err.ERROR), Data: "disk undefind"})
return
@@ -419,3 +460,38 @@ func GetDiskCheck(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
}
// @Summary check mount point
// @Produce application/json
// @Accept application/json
// @Tags disk
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /disk/usb [get]
func GetUSBList(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.Name
temp.Size = v.Size
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children {
if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail
} else {
mountTemp = false
}
}
temp.Mount = mountTemp
data = append(data, temp)
}
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
}

View File

@@ -2,6 +2,7 @@ package v1
import (
"bytes"
"encoding/json"
json2 "encoding/json"
"net/http"
"reflect"
@@ -145,6 +146,7 @@ func SpeedPush(c *gin.Context) {
// @Router /app/install/{id} [post]
func InstallApp(c *gin.Context) {
appId := c.Param("id")
language := c.GetHeader("Language")
var appInfo model.ServerAppList
m := model.CustomizationPostData{}
c.BindJSON(&m)
@@ -174,7 +176,7 @@ func InstallApp(c *gin.Context) {
dockerImageVersion = "latest"
}
if m.Origin != "custom" {
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "")
appInfo = service.MyService.OAPI().GetServerAppInfo(appId, "", language)
} else {
@@ -253,9 +255,11 @@ func InstallApp(c *gin.Context) {
installLog.State = 0
installLog.CustomId = id
installLog.Message = "installing rely"
installLog.Class = types.NOTIFY_APP
installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
installLog.Id = uuid.NewV4().String()
service.MyService.Notify().AddLog(installLog)
if m.Origin != "custom" {
for _, plugin := range appInfo.Plugins {
@@ -441,6 +445,8 @@ func InstallApp(c *gin.Context) {
envsStr, _ := json2.Marshal(m.Envs)
volumesStr, _ := json2.Marshal(m.Volumes)
devicesStr, _ := json2.Marshal(m.Devices)
cmd, _ := json2.Marshal(m.Cmd)
capAdd, _ := json.Marshal(m.CapAdd)
//step: 保存数据到数据库
md := model2.AppListDBModel{
CustomId: id,
@@ -468,9 +474,13 @@ func InstallApp(c *gin.Context) {
Memory: m.Memory,
Devices: string(devicesStr),
//Rely: rely,
Origin: m.Origin,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
Origin: m.Origin,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
Cmd: string(cmd),
CapAdd: string(capAdd),
HostName: m.HostName,
Privileged: m.Privileged,
}
//if appInfo.NetworkModel == "host" {
// m.PortMap = m.Port
@@ -714,7 +724,7 @@ func UnInstallApp(c *gin.Context) {
}
//step: 删除install log
service.MyService.Notify().DelLog(appId)
//service.MyService.Notify().DelLog(appId)
// for k, v := range info.Rely {
//
@@ -754,6 +764,13 @@ func UnInstallApp(c *gin.Context) {
//}
}
config.CasaOSGlobalVariables.AppChange = true
unInstallLog := model2.AppNotify{}
unInstallLog.State = 0
unInstallLog.CustomId = appId
unInstallLog.Message = "uninstalled"
unInstallLog.Id = uuid.NewV4().String()
service.MyService.Notify().UpdateLog(unInstallLog)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
@@ -925,7 +942,9 @@ func UpdateSetting(c *gin.Context) {
envsStr, _ := json2.Marshal(m.Envs)
volumesStr, _ := json2.Marshal(m.Volumes)
devicesStr, _ := json2.Marshal(m.Devices)
if !reflect.DeepEqual(string(portsStr), appInfo.Ports) || !reflect.DeepEqual(string(envsStr), appInfo.Envs) || !reflect.DeepEqual(string(volumesStr), appInfo.Volumes) || m.PortMap != appInfo.PortMap || m.NetworkModel != appInfo.NetModel {
capAddStr, _ := json2.Marshal(m.CapAdd)
cmdStr, _ := json.Marshal(m.Cmd)
if !reflect.DeepEqual(string(portsStr), appInfo.Ports) || !reflect.DeepEqual(string(envsStr), appInfo.Envs) || !reflect.DeepEqual(string(volumesStr), appInfo.Volumes) || m.PortMap != appInfo.PortMap || m.NetworkModel != appInfo.NetModel || m.HostName != appInfo.HostName || !reflect.DeepEqual(string(cmdStr), appInfo.Cmd) || !reflect.DeepEqual(string(capAddStr), appInfo.CapAdd) || m.Privileged != appInfo.Privileged {
var newUUid = uuid.NewV4().String()
var err error
@@ -1043,6 +1062,10 @@ func UpdateSetting(c *gin.Context) {
appInfo.Restart = m.Restart
appInfo.Memory = m.Memory
appInfo.CpuShares = m.CpuShares
appInfo.Cmd = string(cmdStr)
appInfo.Privileged = m.Privileged
appInfo.CapAdd = string(capAddStr)
appInfo.HostName = m.HostName
appInfo.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
service.MyService.App().UpdateApp(appInfo)
@@ -1138,7 +1161,6 @@ func ContainerRelyInfo(c *gin.Context) {
func ContainerUpdateInfo(c *gin.Context) {
appId := c.Param("id")
appInfo := service.MyService.App().GetAppDBInfo(appId)
info, err := service.MyService.Docker().DockerContainerInfo(appId)
if err != nil {
//todo 需要自定义错误
@@ -1161,6 +1183,10 @@ func ContainerUpdateInfo(c *gin.Context) {
var dir model.PathArray
json2.Unmarshal([]byte(appInfo.Devices), &dir)
var cmd []string
json2.Unmarshal([]byte(appInfo.Cmd), &cmd)
var capAdd []string
json2.Unmarshal([]byte(appInfo.CapAdd), &capAdd)
//volumesStr, _ := json2.Marshal(m.Volumes)
//devicesStr, _ := json2.Marshal(m.Devices)
m := model.CustomizationPostData{}
@@ -1182,6 +1208,11 @@ func ContainerUpdateInfo(c *gin.Context) {
m.EnableUPNP = appInfo.EnableUPNP
m.Position = appInfo.Position
m.CapAdd = capAdd
m.Cmd = cmd
m.HostName = appInfo.HostName
m.Privileged = appInfo.Privileged
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: m})
}

View File

@@ -9,8 +9,7 @@ import (
"net/http"
"os"
"path"
"path/filepath"
"time"
"strings"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -127,12 +126,12 @@ func GetLocalFile(c *gin.Context) {
return
}
// @Summary 下载文件
// @Summary download
// @Produce application/json
// @Accept application/json
// @Tags file
// @Security ApiKeyAuth
// @Param path query string true "路径"
// @Param path query string true "path of file"
// @Success 200 {string} string "ok"
// @Router /file/download [get]
func GetDownloadFile(c *gin.Context) {
@@ -165,7 +164,6 @@ func GetDownloadFile(c *gin.Context) {
c.Header("Content-Transfer-Encoding", "binary")
c.File(filePath)
return
}
// @Summary 获取目录列表
@@ -177,18 +175,18 @@ func GetDownloadFile(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /file/dirpath [get]
func DirPath(c *gin.Context) {
path := c.DefaultQuery("path", "/")
path := c.DefaultQuery("path", "")
info := service.MyService.ZiMa().GetDirPath(path)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
}
// @Summary 重命名目录或文件
// @Summary rename file or dir
// @Produce application/json
// @Accept application/json
// @Tags file
// @Security ApiKeyAuth
// @Param oldpath formData string true "旧的路径"
// @Param newpath formData string true "新路径"
// @Param oldpath formData string true "path of old"
// @Param newpath formData string true "path of new"
// @Success 200 {string} string "ok"
// @Router /file/rename [put]
func RenamePath(c *gin.Context) {
@@ -202,12 +200,12 @@ func RenamePath(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
// @Summary 创建文件夹
// @Summary create folder
// @Produce application/json
// @Accept multipart/form-data
// @Tags file
// @Security ApiKeyAuth
// @Param path formData string false "路径"
// @Param path formData string true "path of folder"
// @Success 200 {string} string "ok"
// @Router /file/mkdir [post]
func MkdirAll(c *gin.Context) {
@@ -240,82 +238,85 @@ func PostCreateFile(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
}
// @Summary 上传文件
// @Summary upload file
// @Produce application/json
// @Accept multipart/form-data
// @Tags file
// @Security ApiKeyAuth
// @Param path formData string false "路径"
// @Param path formData string false "file path"
// @Param file formData file true "file"
// @Success 200 {string} string "ok"
// @Router /file/mkdir [post]
// @Router /file/upload [post]
func PostFileUpload(c *gin.Context) {
file, _, _ := c.Request.FormFile("file")
//file.Read()
f, _, _ := c.Request.FormFile("file")
path := c.Query("path")
//上传文件
if len(path) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
if !file.CheckNotExist(path) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)})
return
}
out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
defer out.Close()
io.Copy(out, file)
_, err := io.Copy(out, f)
if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
return
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
func PutFileMove(c *gin.Context) {
from := "/Users/liangjianli/go/CasaOS"
to := "/Users/liangjianli/go/CasaOS/test"
//t := 1 //是否覆盖
//方法体
stopCh := make(chan int)
f, err := os.Stat(from)
if err != nil {
//未拿到文件信息
fmt.Println("stat", err)
// @Summary copy or move file
// @Produce application/json
// @Accept multipart/form-data
// @Tags file
// @Security ApiKeyAuth
// @Param from formData string true "from path"
// @Param to formData string true "to path"
// @Param t formData string true "action" Enums(move,copy)
// @Success 200 {string} string "ok"
// @Router /file/operate [post]
func PostOperateFileOrDir(c *gin.Context) {
from := c.PostForm("from")
to := c.PostForm("to")
t := c.PostForm("type")
if len(from) == 0 || len(t) == 0 || len(to) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
//未创建新的文件夹
if f.IsDir() {
//from 是文件夹,定义to也是文件夹
if list, err := ioutil.ReadDir(from); err == nil {
for _, v := range list {
time.Sleep(time.Second)
if err = Copy(stopCh, filepath.Join(from, v.Name()), filepath.Join(to, v.Name())); err != nil {
fmt.Printf("copy %s ,err %d", v.Name(), err)
}
}
if t == "move" {
lastPath := from[strings.LastIndex(from, "/")+1:]
if !file.CheckNotExist(to + "/" + lastPath) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_OR_DIR_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)})
return
}
err := os.Rename(from, to+"/"+lastPath)
if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
return
}
} else if t == "copy" {
err := file.CopyDir(from, to)
if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
return
}
} else {
p := filepath.Dir(to)
if _, err = os.Stat(p); err != nil {
if err = os.MkdirAll(p, 0777); err != nil {
fmt.Println("mkdir", err)
}
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
file, err := os.Open(from)
if err != nil {
fmt.Println("open file error ", err)
}
defer file.Close()
out, err := os.Create(to)
if err != nil {
fmt.Println("create to file err", err)
}
defer out.Close()
io.Copy(out, file)
time.Sleep(time.Second * 4)
close(stopCh)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
func Copy(stop chan int, from, to string) error {
for {
select {
case <-stop:
return nil
default:
fmt.Println(from)
}
func DeleteFile(c *gin.Context) {
path := c.Query("path")
//err := os.Remove(path)
err := os.RemoveAll(path)
if err != nil {
fmt.Println(err)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_DELETE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.FILE_DELETE_ERROR), Data: err})
return
}
return nil
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}

View File

@@ -1,15 +1,13 @@
package v1
import (
json2 "encoding/json"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"fmt"
"net/http"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"net/http"
"time"
)
var upGrader = websocket.Upgrader{
@@ -33,24 +31,17 @@ func NotifyWS(c *gin.Context) {
return
}
defer ws.Close()
service.WebSocketConns = append(service.WebSocketConns, ws)
if !service.SocketRun {
service.SocketRun = true
service.SendMeg()
}
for {
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
if string(message) != "notify" {
return
}
for {
list := service.MyService.Notify().GetList()
json, _ := json2.Marshal(list)
err = ws.WriteMessage(mt, json)
if err != nil {
break
}
time.Sleep(time.Second * 2)
}
fmt.Println(mt, message, err)
}
}
// @Summary 标记notify已读
@@ -62,9 +53,10 @@ func NotifyWS(c *gin.Context) {
// @Router /notify/read/{id} [put]
func PutNotifyRead(c *gin.Context) {
id := c.Param("id")
if len(id) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
return
}
// if len(id) == 0 {
// c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
// return
// }
fmt.Println(id)
service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
}

25
route/v1/persion.go Normal file
View File

@@ -0,0 +1,25 @@
package v1
import (
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
)
func PersonTest(c *gin.Context) {
//service.MyService.Person().GetPersionInfo("fb2333a1-72b2-4cb4-9e31-61ccaffa55b9")
m := model.ConnectState{}
m.CreatedAt = time.Now()
m.From = config.ServerInfo.Token
m.To = "fb2333a1-72b2-4cb4-9e31-61ccaffa55b9"
m.Type = ""
m.UUId = uuid.NewV4().String()
service.MyService.Person().Handshake(m)
}

View File

@@ -259,9 +259,9 @@ func PostKillCasaOS(c *gin.Context) {
// @Success 200 {string} string "ok"
// @Router /sys/info [get]
func Info(c *gin.Context) {
var data = make(map[string]interface{}, 5)
var data = make(map[string]interface{}, 6)
list := service.MyService.Disk().LSBLK()
list := service.MyService.Disk().LSBLK(true)
summary := model.Summary{}
healthy := true
@@ -269,24 +269,42 @@ func Info(c *gin.Context) {
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 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 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" {
if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" {
temp := service.MyService.Disk().SmartCTL(list[i].Path)
if reflect.DeepEqual(temp, model.SmartctlA{}) {
continue
@@ -312,6 +330,33 @@ func Info(c *gin.Context) {
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
mountTemp := true
if len(v.Children) == 0 {
mountTemp = false
}
for _, child := range v.Children {
if len(child.MountPoint) > 0 {
avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
temp.Avail += avail
used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
temp.Used += used
} else {
mountTemp = false
}
}
temp.Mount = mountTemp
usb = append(usb, temp)
}
}
data["usb"] = usb
cpu := service.MyService.ZiMa().GetCpuPercent()
num := service.MyService.ZiMa().GetCpuCoreNum()
cpuData := make(map[string]interface{})

View File

@@ -2,12 +2,13 @@ package v1
import (
json2 "encoding/json"
"net/http"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
"net/http"
)
// @Summary 登录zerotier获取token
@@ -432,11 +433,17 @@ func ZeroTierDeleteNetwork(c *gin.Context) {
// @Router /zerotier/join/{id} [post]
func ZeroTierJoinNetwork(c *gin.Context) {
networkId := c.Param("id")
service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
if len(networkId) == 0 {
if len(networkId) != 16 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
for _, v := range networkId {
if !service.MyService.ZeroTier().NetworkIdFilter(v) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
}
service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
@@ -450,10 +457,19 @@ func ZeroTierJoinNetwork(c *gin.Context) {
// @Router /zerotier/leave/{id} [post]
func ZeroTierLeaveNetwork(c *gin.Context) {
networkId := c.Param("id")
service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)
if len(networkId) == 0 {
if len(networkId) != 16 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
for _, v := range networkId {
if !service.MyService.ZeroTier().NetworkIdFilter(v) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
}
service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}

View File

@@ -1,6 +1,7 @@
package service
import (
"encoding/json"
json2 "encoding/json"
"fmt"
"strconv"
@@ -13,11 +14,12 @@ import (
)
type CasaService interface {
GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList)
GetServerList(index, size, tp, categoryId, key, language string) (recommend, list, community []model.ServerAppList)
GetServerCategoryList() []model.ServerCategoryList
GetTaskList(size int) []model2.TaskDBModel
GetServerAppInfo(id, t string) model.ServerAppList
GetServerAppInfo(id, t string, language string) model.ServerAppList
ShareAppFile(body []byte) string
PushHeart(id, t string, language string)
}
type casaService struct {
@@ -45,9 +47,9 @@ func (o *casaService) GetTaskList(size int) []model2.TaskDBModel {
return list
}
func (o *casaService) GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList) {
func (o *casaService) GetServerList(index, size, tp, categoryId, key, language string) (recommend, list, community []model.ServerAppList) {
keyName := fmt.Sprintf("list_%s_%s_%s_%s", index, size, tp, categoryId)
keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, language)
if result, ok := Cache.Get(keyName); ok {
res, ok := result.(string)
@@ -63,7 +65,7 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key string) (re
head["Authorization"] = GetToken()
listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/newlist?index="+index+"&size="+size+"&rank="+tp+"&category_id="+categoryId+"&key="+key, head)
listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/newlist?index="+index+"&size="+size+"&rank="+tp+"&category_id="+categoryId+"&key="+key+"&language="+language, head)
json2.Unmarshal([]byte(gjson.Get(listS, "data.list").String()), &list)
json2.Unmarshal([]byte(gjson.Get(listS, "data.recommend").String()), &recommend)
@@ -88,12 +90,12 @@ func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
return list
}
func (o *casaService) GetServerAppInfo(id, t string) model.ServerAppList {
func (o *casaService) GetServerAppInfo(id, t string, language string) model.ServerAppList {
head := make(map[string]string)
head["Authorization"] = GetToken()
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t, head)
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id+"?t="+t+"&language="+language, head)
info := model.ServerAppList{}
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
@@ -123,6 +125,24 @@ func GetToken() string {
return auth
}
func (o *casaService) PushHeart(id, t string, language string) {
m := model.CasaOSHeart{}
m.UuId = id
m.Type = t
b, _ := json.Marshal(m)
head := make(map[string]string)
head["Authorization"] = GetToken()
infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/heart", b, "application/json", head)
info := model.ServerAppList{}
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
}
func NewOasisService() CasaService {
return &casaService{}
}

View File

@@ -20,7 +20,7 @@ import (
type DiskService interface {
GetPlugInDisk() []string
LSBLK() []model.LSBLKModel
LSBLK(isUseCache bool) []model.LSBLKModel
SmartCTL(path string) model.SmartctlA
FormatDisk(path, format string) []string
UmountPointAndRemoveDir(path string) []string
@@ -119,11 +119,11 @@ func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
}
//get disk details
func (d *diskService) LSBLK() []model.LSBLKModel {
func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel {
key := "system_lsblk"
var n []model.LSBLKModel
if result, ok := Cache.Get(key); ok {
if result, ok := Cache.Get(key); ok && isUseCache {
res, ok := result.([]model.LSBLKModel)
if ok {
@@ -247,12 +247,12 @@ func (d *diskService) MountDisk(path, volume string) {
}
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
d.db.Where("serial = ?", m.Serial).Delete(&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("serial = ?", m.Serial).Update("mount_point", m.MountPoint)
d.db.Model(&model2.SerialDisk{}).Where("uui = ?", m.UUID).Update("mount_point", m.MountPoint)
}
func (d *diskService) DeleteMount(id string) {

View File

@@ -433,7 +433,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
}
for _, p := range m.Devices {
if len(p.Path) > 0 {
res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath})
res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath, CgroupPermissions: "rwm"})
}
}
hostConfingBind := []string{}
@@ -490,13 +490,18 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
// Retries: 1000,
// }
// fmt.Print(health)
if len(m.HostName) == 0 {
m.HostName = m.Label
}
config := &container.Config{
Image: imageName,
Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin},
Env: envArr,
// Healthcheck: health,
Hostname: m.HostName,
Cmd: m.Cmd,
}
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net)}
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net), Privileged: m.Privileged, CapAdd: m.CapAdd}
//if net != "host" {
config.ExposedPorts = ports
hostConfig.PortBindings = portMaps
@@ -754,7 +759,7 @@ func (ds *dockerService) DockerContainerUpdate(m model.CustomizationPostData, id
res.CPUShares = m.CpuShares
}
for _, p := range m.Devices {
res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath})
res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath, CgroupPermissions: "rwm"})
}
_, err = cli.ContainerUpdate(context.Background(), id, container.UpdateConfig{RestartPolicy: rp, Resources: res})
if err != nil {

View File

@@ -40,7 +40,11 @@ type AppListDBModel struct {
Memory int64 `json:"memory"`
Restart string `json:"restart"`
//Rely model.MapStrings `gorm:"type:json" json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
Origin string `json:"origin"`
Origin string `json:"origin"`
HostName string `json:"host_name"`
Privileged bool `json:"privileged"`
CapAdd string `json:"cap_add"`
Cmd string `gorm:"type:json" json:"cmd"`
}
func (p *AppListDBModel) TableName() string {

View File

@@ -3,7 +3,7 @@ package model
//SerialAdvanced Technology Attachment (STAT)
type SerialDisk struct {
Id uint `gorm:"column:id;primary_key" json:"id"`
Serial string `json:"serial"`
UUID string `json:"uuid"`
Path string `json:"path"`
State int `json:"state"`
MountPoint string `json:"mount_point"`

View File

@@ -6,9 +6,10 @@ type AppNotify struct {
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Id string `json:"id"`
Type int `json:"type"` // 1:显示即为已读 2:info 3:warning 4:error 5:success
Type int `json:"type"`
Icon string `json:"icon"`
Name string `json:"name"`
Class int `json:"class"`
CustomId string `gorm:"column:custom_id;primary_key" json:"custom_id"`
}

View File

@@ -1,8 +1,12 @@
package service
import (
json2 "encoding/json"
"time"
"github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gorilla/websocket"
"gorm.io/gorm"
)
@@ -10,8 +14,9 @@ type NotifyServer interface {
GetLog(id string) model.AppNotify
AddLog(log model.AppNotify)
UpdateLog(log model.AppNotify)
UpdateLogByCustomId(log model.AppNotify)
DelLog(id string)
GetList() (list []model.AppNotify)
GetList(c int) (list []model.AppNotify)
MarkRead(id string, state int)
}
@@ -19,8 +24,8 @@ type notifyServer struct {
db *gorm.DB
}
func (i notifyServer) GetList() (list []model.AppNotify) {
i.db.Where("state=? or state=?", types.NOTIFY_DYNAMICE, types.NOTIFY_UNREAD).Find(&list)
func (i notifyServer) GetList(c int) (list []model.AppNotify) {
i.db.Where("class = ?", c).Where(i.db.Where("state = ?", types.NOTIFY_DYNAMICE).Or("state = ?", types.NOTIFY_UNREAD)).Find(&list)
return
}
@@ -31,20 +36,72 @@ func (i *notifyServer) AddLog(log model.AppNotify) {
func (i *notifyServer) UpdateLog(log model.AppNotify) {
i.db.Save(&log)
}
func (i *notifyServer) UpdateLogByCustomId(log model.AppNotify) {
if len(log.CustomId) == 0 {
return
}
i.db.Model(&model.AppNotify{}).Select("*").Where("custom_id = ? ", log.CustomId).Updates(log)
}
func (i *notifyServer) GetLog(id string) model.AppNotify {
var log model.AppNotify
i.db.Where("custom_id = ? ", id).First(&log)
return log
}
func (i *notifyServer) MarkRead(id string, state int) {
i.db.Update("state=", state).Where("custom_id = ? ", id)
if id == "0" {
i.db.Model(&model.AppNotify{}).Where("1 = ?", 1).Update("state", state)
return
}
i.db.Model(&model.AppNotify{}).Where("id = ? ", id).Update("state", state)
}
func (i *notifyServer) DelLog(id string) {
var log model.AppNotify
i.db.Where("custom_id = ?", id).Delete(&log)
}
func SendMeg() {
// for {
// mt, message, err := ws.ReadMessage()
// if err != nil {
// break
// }
// notify := model.NotifyMssage{}
// json2.Unmarshal(message, &notify)
// if notify.Type == "read" {
// service.MyService.Notify().MarkRead(notify.Data, types.NOTIFY_READ)
// }
// if notify.Type == "app" {
// go func(ws *websocket.Conn) {
for {
list := MyService.Notify().GetList(types.NOTIFY_APP)
json, _ := json2.Marshal(list)
if len(list) > 0 {
var temp []*websocket.Conn
for _, v := range WebSocketConns {
err := v.WriteMessage(1, json)
if err == nil {
temp = append(temp, v)
}
}
WebSocketConns = temp
for _, v := range list {
MyService.Notify().MarkRead(v.Id, types.NOTIFY_READ)
}
}
if len(WebSocketConns) == 0 {
SocketRun = false
}
time.Sleep(time.Second * 2)
}
// }(ws)
// }
// }
}
func NewNotifyService(db *gorm.DB) NotifyServer {
return &notifyServer{db: db}
}

117
service/person.go Normal file
View File

@@ -0,0 +1,117 @@
package service
import (
"encoding/json"
"fmt"
"log"
"net"
"reflect"
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
)
type PersonService interface {
GetPersionInfo(token string) (m model.PersionModel, err error)
Handshake(m model.ConnectState)
}
type personService struct {
}
var IpInfo model.PersionModel
func PushIpInfo(token string) {
m := model.PersionModel{}
m.Ips = GetDeviceAllIP()
m.Token = token
b, _ := json.Marshal(m)
if reflect.DeepEqual(IpInfo, m) {
return
}
head := make(map[string]string)
infoS := httper2.Post(config.ServerInfo.Handshake+"/v1/update", b, "application/json", head)
fmt.Println(infoS)
}
func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err error) {
infoS := httper2.Get(config.ServerInfo.Handshake+"/v1/ips/"+token, nil)
err = json.Unmarshal([]byte(infoS), &m)
return
}
//尝试连接
func (p *personService) Handshake(m model.ConnectState) {
//1先进行udp打通成功
srcAddr := &net.UDPAddr{
IP: net.IPv4zero, Port: 9901} //注意端口必须固定
dstAddr := &net.UDPAddr{
IP: net.ParseIP(config.ServerInfo.Handshake), Port: 9527}
//DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6"如果laddr不是nil将使用它作为本地地址否则自动选择一个本地地址。
//(conn)UDPConn代表一个UDP网络连接实现了Conn和PacketConn接口
conn, err := net.DialUDP("udp", srcAddr, dstAddr)
if err != nil {
fmt.Println(err)
}
b, _ := json.Marshal(m)
if _, err = conn.Write(b); err != nil {
fmt.Println(err)
}
data := make([]byte, 1024)
//ReadFromUDP从c读取一个UDP数据包将有效负载拷贝到b返回拷贝字节数和数据包来源地址。
//ReadFromUDP方***在超过一个固定的时间点之后超时,并返回一个错误。
n, _, err := conn.ReadFromUDP(data)
if err != nil {
fmt.Printf("error during read: %s", err)
}
conn.Close()
toPersion := model.PersionModel{}
err = json.Unmarshal(data[:n], &toPersion)
if err != nil {
fmt.Println(err)
}
// bidirectionHole(srcAddr, &anotherPeer)
//2udp打洞成功向服务器汇报打洞结果
//3转udp打洞
}
func bidirectionHole(srcAddr *net.UDPAddr, anotherAddr *net.UDPAddr) {
conn, err := net.DialUDP("udp", srcAddr, anotherAddr)
if err != nil {
fmt.Println("send handshake:", err)
}
go func() {
for {
time.Sleep(10 * time.Second)
if _, err = conn.Write([]byte("from []")); err != nil {
log.Println("send msg fail", err)
}
}
}()
for {
data := make([]byte, 1024)
n, _, err := conn.ReadFromUDP(data)
if err != nil {
log.Printf("error during read:%s\n", err)
} else {
log.Printf("收到数据:%s\n", data[:n])
}
}
}
func NewPersonService() PersonService {
return &personService{}
}

View File

@@ -2,6 +2,7 @@ package service
import (
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/gorilla/websocket"
"github.com/patrickmn/go-cache"
"gorm.io/gorm"
)
@@ -10,6 +11,10 @@ var Cache *cache.Cache
var MyService Repository
var WebSocketConns []*websocket.Conn
var SocketRun bool
type Repository interface {
App() AppService
DDNS() DDNSService
@@ -27,6 +32,7 @@ type Repository interface {
System() SystemService
Shortcuts() ShortcutsService
Search() SearchService
Person() PersonService
}
func NewService(db *gorm.DB, log loger2.OLog) Repository {
@@ -48,6 +54,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
system: NewSystemService(log),
shortcuts: NewShortcutsService(db),
search: NewSearchService(),
person: NewPersonService(),
}
}
@@ -68,6 +75,7 @@ type store struct {
system SystemService
shortcuts ShortcutsService
search SearchService
person PersonService
}
func (c *store) Rely() RelyService {
@@ -76,6 +84,9 @@ func (c *store) Rely() RelyService {
func (c *store) Shortcuts() ShortcutsService {
return c.shortcuts
}
func (c *store) Person() PersonService {
return c.person
}
func (c *store) System() SystemService {
return c.system
}

View File

@@ -2,6 +2,7 @@ package service
import (
"io/ioutil"
"net"
"os"
"github.com/IceWhaleTech/CasaOS/pkg/config"
@@ -71,6 +72,21 @@ func (s *systemService) GetCasaOSLogs(lineNumber int) string {
return string(content)
}
func GetDeviceAllIP() []string {
var address []string
addrs, err := net.InterfaceAddrs()
if err != nil {
return address
}
for _, a := range addrs {
if ipNet, ok := a.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
if ipNet.IP.To16() != nil {
address = append(address, ipNet.IP.String())
}
}
}
return address
}
func NewSystemService(log loger.OLog) SystemService {
return &systemService{log: log}
}

View File

@@ -28,10 +28,6 @@ func (c *user) SetUser(username, pwd, token, email, desc string) error {
config.Cfg.Section("user").Key("PWD").SetValue(pwd)
config.UserInfo.PWD = pwd
}
if len(token) > 0 {
config.Cfg.Section("user").Key("Token").SetValue(token)
config.UserInfo.Token = token
}
if len(email) > 0 {
config.Cfg.Section("user").Key("Email").SetValue(email)
config.UserInfo.Email = email

View File

@@ -4,18 +4,20 @@ import (
"bytes"
"errors"
"fmt"
"github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/pkg/zerotier"
"github.com/PuerkitoBio/goquery"
"github.com/tidwall/gjson"
"io/ioutil"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
"unicode"
"github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/pkg/zerotier"
"github.com/PuerkitoBio/goquery"
"github.com/tidwall/gjson"
)
type ZeroTierService interface {
@@ -33,6 +35,7 @@ type ZeroTierService interface {
DeleteMember(token string, id, mId string) interface{}
DeleteNetwork(token, id string) interface{}
GetJoinNetworks() string
NetworkIdFilter(letter rune) bool
}
type zerotierStruct struct {
}
@@ -333,6 +336,13 @@ func (c *zerotierStruct) GetJoinNetworks() string {
return json
}
func (c *zerotierStruct) NetworkIdFilter(letter rune) bool {
if unicode.IsNumber(letter) || unicode.IsLetter(letter) {
return true
} else {
return false
}
}
func NewZeroTierService() ZeroTierService {
//初始化client
client = http.Client{Timeout: 30 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error {

View File

@@ -85,7 +85,7 @@ func (c *zima) GetDirPath(path string) []model.Path {
ls, _ := ioutil.ReadDir(path)
dirs := []model.Path{}
if strings.Count(path, "/") > 0 {
if len(path) > 0 {
for _, l := range ls {
dirs = append(dirs, model.Path{Name: l.Name(), Path: path + "/" + l.Name(), IsDir: l.IsDir(), Date: l.ModTime()})
}

View File

@@ -11,7 +11,7 @@ version_0_2_3() {
# add in v0.2.5
readonly CASA_DEPANDS="curl smartmontools parted fdisk partprobe"
readonly CASA_DEPANDS="curl smartmontools parted fdisk ntfs-3g"
version_0_2_5() {
install_depends "$CASA_DEPANDS"
@@ -22,7 +22,6 @@ version_0_2_5() {
install_depends() {
((EUID)) && sudo_cmd="sudo"
if [[ ! -x "$(command -v '$1')" ]]; then
show 2 "Install the necessary dependencies: $1"
packagesNeeded=$1
if [ -x "$(command -v apk)" ]; then
$sudo_cmd apk add --no-cache $packagesNeeded
@@ -32,8 +31,6 @@ install_depends() {
$sudo_cmd dnf install $packagesNeeded
elif [ -x "$(command -v zypper)" ]; then
$sudo_cmd zypper install $packagesNeeded
else
show 1 "Package manager not found. You must manually install: $packagesNeeded"
fi
fi
}

View File

@@ -115,8 +115,8 @@ AddPartition() {
parted -s $1 mklabel gpt
parted -s $1 mkpart primary ext4 0 100%
mkfs.ext4 -m 1 $11
PATH=`lsblk -r $1 | sort | grep part | head -n 1 | awk '{print $1}'`
mkfs.ext4 -m 1 /dev/${PATH}
partprobe $1
@@ -156,8 +156,8 @@ GetPartitionSectors() {
#检查没有使用的挂载点删除文件夹
AutoRemoveUnuseDir() {
DIRECTORY="/mnt/"
dir=$(ls -l $DIRECTORY | awk '/^d/ {print $NF}')
DIRECTORY="/DATA/"
dir=$(ls -l $DIRECTORY | grep "Storage[0-9]" | awk '/^d/ {print $NF}')
for i in $dir; do
path="$DIRECTORY$i"
@@ -184,7 +184,7 @@ do_mount() {
DEVBASE=$1
DEVICE="${DEVBASE}"
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
MOUNT_POINT=$(lsblk -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
if [ -n "${MOUNT_POINT}" ]; then
${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"

View File

@@ -12,7 +12,7 @@ DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
MOUNT_POINT=$(lsblk -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
do_mount() {

View File

@@ -11,3 +11,7 @@ const (
NOTIFY_TYPE_ERROR
NOTIFY_TYPE_INSTALL_LOG
)
const (
NOTIFY_APP = iota
)

View File

@@ -1,5 +1,5 @@
package types
const CURRENTVERSION = "0.2.6"
const CURRENTVERSION = "0.2.9"
const BODY = "<li>Fix a disk that cannot be formatted under certain circumstances</li>"
const BODY = "<li>Custom installation of new parameters</li><li>Fixed issues</li><li>Update front-end translation</li>"

BIN
web/img/USB.3ba78dec.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

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