New App Store
This commit is contained in:
parent
1d62fbd670
commit
1d17d27c96
25 changed files with 689 additions and 227 deletions
2
UI
2
UI
|
@ -1 +1 @@
|
|||
Subproject commit 65d4738a607ec28f22bffb1d489dd284c360d2ce
|
||||
Subproject commit f3088b635482fd4330c3fce6bbfcd1f70ff8024a
|
|
@ -15,6 +15,7 @@ type ServerAppList struct {
|
|||
Icon string `json:"icon"`
|
||||
ScreenshotLink Strings `gorm:"type:json" json:"screenshot_link"`
|
||||
Category string `json:"category"`
|
||||
CategoryFont string `json:"category_font"`
|
||||
PortMap string `json:"port_map"`
|
||||
ImageVersion string `json:"image_version"`
|
||||
Tip string `json:"tip"`
|
||||
|
@ -36,6 +37,8 @@ type ServerAppList struct {
|
|||
Healthy string `json:"healthy"`
|
||||
Plugins Strings `json:"plugins"`
|
||||
Origin string `json:"origin"`
|
||||
Type int `json:"type"`
|
||||
Developer string `json:"developer"`
|
||||
}
|
||||
|
||||
type Ports struct {
|
||||
|
|
|
@ -5,6 +5,7 @@ type ServerCategoryList struct {
|
|||
//CreatedAt time.Time `json:"created_at"`
|
||||
//
|
||||
//UpdatedAt time.Time `json:"updated_at"`
|
||||
Font string `json:"font"`
|
||||
Name string `json:"name"`
|
||||
Count uint `json:"count"`
|
||||
}
|
||||
|
|
|
@ -3,33 +3,9 @@ package docker
|
|||
import "strings"
|
||||
|
||||
func GetDir(id, envName string) string {
|
||||
var path string
|
||||
|
||||
if len(id) == 0 {
|
||||
id = "$AppID"
|
||||
if strings.Contains(envName, "$AppID") && len(id) > 0 {
|
||||
return strings.ReplaceAll(envName, "$AppID", id)
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.Contains(strings.ToLower(envName), "config") || strings.Contains(strings.ToLower(envName), "photoprism/storage") || strings.Contains(strings.ToLower(envName), "config"):
|
||||
path = "/DATA/AppData/" + id + "/"
|
||||
case strings.Contains(strings.ToLower(envName), "media"):
|
||||
path = "/DATA/Media/"
|
||||
case strings.Contains(strings.ToLower(envName), "movie"):
|
||||
path = "/DATA/Media/Movies/"
|
||||
case strings.Contains(strings.ToLower(envName), "music"):
|
||||
path = "/DATA/Media/Music/"
|
||||
case strings.Contains(strings.ToLower(envName), "photoprism/originals"):
|
||||
path = "/DATA/Gallery"
|
||||
case strings.Contains(strings.ToLower(envName), "download"):
|
||||
path = "/DATA/Downloads/"
|
||||
case strings.Contains(strings.ToLower(envName), "photo") || strings.Contains(strings.ToLower(envName), "pictures"):
|
||||
path = "/DATA/Downloads/"
|
||||
case strings.ToLower(envName) == "/srv":
|
||||
path = "/DATA/"
|
||||
case strings.ToLower(envName) == "/tv":
|
||||
path = "/DATA/Media/TV Shows"
|
||||
default:
|
||||
//path = "/media"
|
||||
}
|
||||
return path
|
||||
return envName
|
||||
}
|
||||
|
|
|
@ -2,11 +2,12 @@ package sqlite
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
var gdb *gorm.DB
|
||||
|
@ -30,7 +31,7 @@ func GetDb(projectPath string) *gorm.DB {
|
|||
return nil
|
||||
}
|
||||
gdb = db
|
||||
err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{})
|
||||
err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{})
|
||||
if err != nil {
|
||||
fmt.Println("检查和创建数据库出错", err)
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ func ExecResultStr(cmdStr string) string {
|
|||
func ExecLSBLK() []byte {
|
||||
output, err := exec.Command("lsblk", "-O", "-J", "-b").Output()
|
||||
if err != nil {
|
||||
fmt.Println("lsblk", err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
|
|
|
@ -2,18 +2,25 @@ package env_helper
|
|||
|
||||
import "strings"
|
||||
|
||||
func ReplaceDefaultENV(key string) string {
|
||||
func ReplaceDefaultENV(key, tz string) string {
|
||||
temp := ""
|
||||
switch key {
|
||||
case "$DefaultPassword":
|
||||
temp = "casaos"
|
||||
case "$DefaultUserName":
|
||||
temp = "admin"
|
||||
|
||||
case "$PUID":
|
||||
temp = "1000"
|
||||
case "$PGID":
|
||||
temp = "1000"
|
||||
case "$TZ":
|
||||
temp = tz
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
//replace env default setting
|
||||
func ReplaceStringDefaultENV(str string) string {
|
||||
return strings.ReplaceAll(strings.ReplaceAll(str, "$DefaultPassword", ReplaceDefaultENV("$DefaultPassword")), "$DefaultUserName", ReplaceDefaultENV("$DefaultUserName"))
|
||||
return strings.ReplaceAll(strings.ReplaceAll(str, "$DefaultPassword", ReplaceDefaultENV("$DefaultPassword", "")), "$DefaultUserName", ReplaceDefaultENV("$DefaultUserName", ""))
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
func InitFunction() {
|
||||
go checkSystemApp()
|
||||
Update2_3()
|
||||
CheckSerialDiskMount()
|
||||
|
||||
}
|
||||
|
||||
var syncIsExistence = false
|
||||
|
@ -72,9 +74,6 @@ func installSyncthing(appId string) {
|
|||
appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
|
||||
}
|
||||
|
||||
for i := 0; i < len(appInfo.Volumes); i++ {
|
||||
appInfo.Volumes[i].Path = docker.GetDir("", appInfo.Volumes[i].ContainerPath)
|
||||
}
|
||||
appInfo.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
|
||||
|
||||
id := uuid.NewV4().String()
|
||||
|
@ -171,7 +170,7 @@ func checkSystemApp() {
|
|||
path := ""
|
||||
for _, i := range paths {
|
||||
if i.ContainerPath == "/config" {
|
||||
path = docker.GetDir(v.CustomId, i.ContainerPath) + "config.xml"
|
||||
path = docker.GetDir(v.CustomId, i.Path) + "config.xml"
|
||||
for i := 0; i < 10; i++ {
|
||||
if file.CheckNotExist(path) {
|
||||
time.Sleep(1 * time.Second)
|
||||
|
@ -189,12 +188,31 @@ func checkSystemApp() {
|
|||
}
|
||||
}
|
||||
if !syncIsExistence {
|
||||
installSyncthing("44")
|
||||
installSyncthing("74")
|
||||
}
|
||||
}
|
||||
func CheckSerialDiskMount() {
|
||||
// 检查挂载点重新挂载
|
||||
// 检查新硬盘是否有多个分区,如有多个分区需提示
|
||||
// check mount point
|
||||
dbList := service.MyService.Disk().GetSerialAll()
|
||||
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
mountPoint := make(map[string]string, len(dbList))
|
||||
|
||||
for _, v := range list {
|
||||
if v.Children != nil {
|
||||
for _, h := range v.Children {
|
||||
mountPoint[h.MountPoint] = "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remount
|
||||
for _, item := range dbList {
|
||||
if _, ok := mountPoint[item.MountPoint]; !ok {
|
||||
service.MyService.Disk().MountDisk(item.Path, item.MountPoint)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func Update2_3() {
|
||||
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
|
||||
|
|
|
@ -70,8 +70,7 @@ func InitRouter() *gin.Engine {
|
|||
|
||||
//获取网络信息
|
||||
v1ZiMaGroup.GET("/getnetinfo", v1.NetInfo)
|
||||
//获取网络信息
|
||||
v1ZiMaGroup.GET("/getinfo", v1.Info)
|
||||
|
||||
//获取系统信息
|
||||
v1ZiMaGroup.GET("/sysinfo", v1.SysInfo)
|
||||
}
|
||||
|
@ -197,6 +196,7 @@ func InitRouter() *gin.Engine {
|
|||
v1SysGroup.GET("/port", v1.GetCasaOSPort)
|
||||
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
|
||||
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
|
||||
v1SysGroup.GET("/info", v1.Info)
|
||||
}
|
||||
v1FileGroup := v1Group.Group("/file")
|
||||
v1FileGroup.Use()
|
||||
|
@ -211,11 +211,13 @@ func InitRouter() *gin.Engine {
|
|||
v1FileGroup.POST("/create", v1.PostCreateFile)
|
||||
|
||||
v1FileGroup.GET("/download", v1.GetDownloadFile)
|
||||
v1FileGroup.PUT("/move", v1.PutFileMove)
|
||||
//v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
|
||||
}
|
||||
v1DiskGroup := v1Group.Group("/disk")
|
||||
v1DiskGroup.Use()
|
||||
{
|
||||
v1DiskGroup.GET("/check", v1.GetDiskCheck)
|
||||
//获取磁盘列表
|
||||
v1DiskGroup.GET("/list", v1.GetPlugInDisk)
|
||||
|
||||
|
@ -238,8 +240,8 @@ func InitRouter() *gin.Engine {
|
|||
v1DiskGroup.POST("/mount", v1.PostMountDisk)
|
||||
|
||||
//umount SATA disk
|
||||
v1DiskGroup.POST("/umount", v1.DeleteUmountDisk)
|
||||
|
||||
v1DiskGroup.POST("/umount", v1.PostDiskUmount)
|
||||
v1DiskGroup.DELETE("/remove/:id", v1.DeleteDisk)
|
||||
}
|
||||
v1ShareGroup := v1Group.Group("/share")
|
||||
v1ShareGroup.Use()
|
||||
|
|
|
@ -7,8 +7,6 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/docker"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||
|
@ -33,20 +31,33 @@ func AppList(c *gin.Context) {
|
|||
//service.MyService.Docker().DockerContainerCommit("test2")
|
||||
|
||||
index := c.DefaultQuery("index", "1")
|
||||
size := c.DefaultQuery("size", "10")
|
||||
size := c.DefaultQuery("size", "10000")
|
||||
t := c.DefaultQuery("type", "rank")
|
||||
categoryId := c.DefaultQuery("category_id", "0")
|
||||
key := c.DefaultQuery("key", "")
|
||||
list, count := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
||||
recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
|
||||
for i := 0; i < len(recommend); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(list); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
data := make(map[string]interface{}, 2)
|
||||
data["count"] = count
|
||||
data["items"] = list
|
||||
for i := 0; i < len(community); i++ {
|
||||
ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
|
||||
if ct != nil {
|
||||
list[i].State = ct.State
|
||||
}
|
||||
}
|
||||
data := make(map[string]interface{}, 3)
|
||||
data["recommend"] = recommend
|
||||
data["list"] = list
|
||||
data["community"] = community
|
||||
|
||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
||||
}
|
||||
|
@ -147,6 +158,13 @@ func AppInfo(c *gin.Context) {
|
|||
info.PortMap = info.Ports[i].CommendPort
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < len(info.Ports); i++ {
|
||||
if info.Ports[i].Type == 0 {
|
||||
info.PortMap = info.Ports[i].ContainerPort
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(info.Devices); i++ {
|
||||
|
@ -154,13 +172,10 @@ func AppInfo(c *gin.Context) {
|
|||
info.Devices[i].Path = info.Devices[i].ContainerPath
|
||||
}
|
||||
}
|
||||
if len(info.Tip) > 0 {
|
||||
info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
|
||||
}
|
||||
// if len(info.Tip) > 0 {
|
||||
// info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
|
||||
// }
|
||||
|
||||
for i := 0; i < len(info.Volumes); i++ {
|
||||
info.Volumes[i].Path = docker.GetDir("", info.Volumes[i].ContainerPath)
|
||||
}
|
||||
// portOrder := func(c1, c2 *model.Ports) bool {
|
||||
// return c1.Type < c2.Type
|
||||
// }
|
||||
|
@ -207,7 +222,7 @@ func CategoryList(c *gin.Context) {
|
|||
}
|
||||
|
||||
rear := append([]model.ServerCategoryList{}, list[0:]...)
|
||||
list = append(list[:0], model.ServerCategoryList{Count: count, Name: "All"})
|
||||
list = append(list[:0], model.ServerCategoryList{Count: count, Name: "All", Font: "apps"})
|
||||
list = append(list, rear...)
|
||||
c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
|
||||
}
|
||||
|
|
140
route/v1/disk.go
140
route/v1/disk.go
|
@ -2,10 +2,12 @@ package v1
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
)
|
||||
|
@ -19,44 +21,9 @@ import (
|
|||
// @Router /disk/list [get]
|
||||
func GetPlugInDisk(c *gin.Context) {
|
||||
|
||||
//ls := service.MyService.Disk().GetPlugInDisk()
|
||||
//fmt.Println(ls)
|
||||
//dd, _ := disk.Partitions(true)
|
||||
//fmt.Println(dd)
|
||||
//
|
||||
//dir, err := ioutil.ReadDir("/sys/block")
|
||||
//if err != nil {
|
||||
// panic(err)
|
||||
//}
|
||||
//
|
||||
//files := make([]string, 0)
|
||||
//
|
||||
////fmt.Println(regexp.MatchString("sd[a-z]*[0-9]", "sda"))
|
||||
//
|
||||
//for _, f := range dir {
|
||||
// if match, _ := regexp.MatchString("sd[a-z]", f.Name()); match {
|
||||
// files = append(files, f.Name())
|
||||
// }
|
||||
//}
|
||||
//fmt.Println(files)
|
||||
//filess := make([]string, 0)
|
||||
//for _, file := range files {
|
||||
// dirs, _ := ioutil.ReadDir("/sys/block/" + file)
|
||||
//
|
||||
// for _, f := range dirs {
|
||||
// if match, _ := regexp.MatchString("sd[a-z]*[0-9]", f.Name()); match {
|
||||
// filess = append(filess, f.Name())
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//fmt.Println(filess)
|
||||
//
|
||||
//for _, s := range filess {
|
||||
// fmt.Println(disk.Usage("/dev/" + s))
|
||||
//}
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
|
||||
lst := service.MyService.Disk().LSBLK()
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: lst})
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: list})
|
||||
}
|
||||
|
||||
// @Summary get disk list
|
||||
|
@ -98,7 +65,7 @@ func GetDiskInfo(c *gin.Context) {
|
|||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "磁盘路径 例如/dev/sda1"
|
||||
// @Param path formData string true "for example /dev/sda1"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/format [post]
|
||||
func FormatDisk(c *gin.Context) {
|
||||
|
@ -108,8 +75,8 @@ func FormatDisk(c *gin.Context) {
|
|||
|
||||
if len(path) == 0 || len(t) == 0 {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
|
||||
return
|
||||
}
|
||||
//格式化磁盘
|
||||
service.MyService.Disk().FormatDisk(path, t)
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
|
@ -168,23 +135,106 @@ func AddPartition(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary add mount point
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "for example: /dev/sda1"
|
||||
// @Param serial formData string true "disk id"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/mount [post]
|
||||
func PostMountDisk(c *gin.Context) {
|
||||
// for example: path=/dev/sda1
|
||||
path := c.PostForm("path")
|
||||
//执行挂载目录
|
||||
service.MyService.Disk().MountDisk(path, "volume")
|
||||
//添加到数据库
|
||||
serial := c.PostForm("serial")
|
||||
|
||||
mountPath := "/mnt/volume"
|
||||
var list = service.MyService.Disk().GetSerialAll()
|
||||
var pathMapList = make(map[string]string, len(list))
|
||||
for _, v := range list {
|
||||
pathMapList[v.MountPoint] = "1"
|
||||
}
|
||||
|
||||
for i := 0; i < len(list)+1; i++ {
|
||||
if _, ok := pathMapList[mountPath+strconv.Itoa(i)]; !ok {
|
||||
mountPath = mountPath + strconv.Itoa(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//mount dir
|
||||
service.MyService.Disk().MountDisk(path, mountPath)
|
||||
//save to data
|
||||
m := model2.SerialDisk{}
|
||||
m.MountPoint = mountPath
|
||||
m.Path = path
|
||||
m.Serial = 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)})
|
||||
}
|
||||
|
||||
func DeleteUmountDisk(c *gin.Context) {
|
||||
// @Summary remove mount point
|
||||
// @Produce application/json
|
||||
// @Accept multipart/form-data
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param path formData string true "for example: /dev/sda1"
|
||||
// @Param mount_point formData string true "for example: /mnt/volume1"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/umount [post]
|
||||
func PostDiskUmount(c *gin.Context) {
|
||||
|
||||
// for example: path=/dev/sda1
|
||||
//
|
||||
path := c.PostForm("path")
|
||||
mountPoint := c.PostForm("mount_point")
|
||||
service.MyService.Disk().UmountPointAndRemoveDir(path)
|
||||
|
||||
//删除数据库记录
|
||||
//delete data
|
||||
service.MyService.Disk().DeleteMountPoint(path, mountPoint)
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
||||
// @Summary confirm delete disk
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags disk
|
||||
// @Security ApiKeyAuth
|
||||
// @Param id path string true "id"
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /disk/remove/{id} [delete]
|
||||
func DeleteDisk(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
service.MyService.Disk().DeleteMount(id)
|
||||
c.JSON(http.StatusOK, model.Result{Success: 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/init [get]
|
||||
func GetDiskCheck(c *gin.Context) {
|
||||
|
||||
dbList := service.MyService.Disk().GetSerialAll()
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
|
||||
mapList := make(map[string]string)
|
||||
|
||||
for _, v := range list {
|
||||
mapList[v.Serial] = "1"
|
||||
}
|
||||
|
||||
for _, v := range dbList {
|
||||
if _, ok := mapList[v.Serial]; !ok {
|
||||
//disk undefind
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.ERROR, Message: oasis_err.GetMsg(oasis_err.ERROR), Data: "disk undefind"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS)})
|
||||
}
|
||||
|
|
|
@ -218,14 +218,24 @@ func InstallApp(c *gin.Context) {
|
|||
}
|
||||
|
||||
}
|
||||
if m.Origin == "custom" {
|
||||
for _, device := range m.Devices {
|
||||
if file.CheckNotExist(device.Path) {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.DEVICE_NOT_EXIST, Message: device.Path + "," + oasis_err2.GetMsg(oasis_err2.DEVICE_NOT_EXIST)})
|
||||
return
|
||||
}
|
||||
|
||||
for _, device := range m.Devices {
|
||||
if file.CheckNotExist(device.Path) {
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.DEVICE_NOT_EXIST, Message: device.Path + "," + oasis_err2.GetMsg(oasis_err2.DEVICE_NOT_EXIST)})
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
dev := []model.PathMap{}
|
||||
for _, device := range dev {
|
||||
if !file.CheckNotExist(device.Path) {
|
||||
dev = append(dev, device)
|
||||
}
|
||||
}
|
||||
m.Devices = dev
|
||||
}
|
||||
|
||||
//restart := c.PostForm("restart") //always 总是重启, unless-stopped 除非用户手动停止容器,否则总是重新启动, on-failure:仅当容器退出代码非零时重新启动
|
||||
//if len(restart) > 0 {
|
||||
//
|
||||
|
@ -421,11 +431,11 @@ func InstallApp(c *gin.Context) {
|
|||
rely := model.MapStrings{}
|
||||
|
||||
copier.Copy(&rely, &relyMap)
|
||||
if m.Origin != "custom" {
|
||||
for i := 0; i < len(m.Volumes); i++ {
|
||||
m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].ContainerPath)
|
||||
}
|
||||
}
|
||||
// if m.Origin != "custom" {
|
||||
// for i := 0; i < len(m.Volumes); i++ {
|
||||
// m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].Path)
|
||||
// }
|
||||
// }
|
||||
|
||||
portsStr, _ := json2.Marshal(m.Ports)
|
||||
envsStr, _ := json2.Marshal(m.Envs)
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
|
@ -256,3 +258,64 @@ func PostFileUpload(c *gin.Context) {
|
|||
io.Copy(out, file)
|
||||
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)
|
||||
}
|
||||
//未创建新的文件夹
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p := filepath.Dir(to)
|
||||
if _, err = os.Stat(p); err != nil {
|
||||
if err = os.MkdirAll(p, 0777); err != nil {
|
||||
fmt.Println("mkdir", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
func Copy(stop chan int, from, to string) error {
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stop:
|
||||
return nil
|
||||
default:
|
||||
fmt.Println(from)
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,11 +6,14 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/version"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
|
@ -127,8 +130,9 @@ func GetWidgetConfig(c *gin.Context) {
|
|||
func PostSetWidgetConfig(c *gin.Context) {
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := c.Request.Body.Read(buf)
|
||||
|
||||
fmt.Println("错误", strconv.Itoa(n))
|
||||
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
|
||||
fmt.Println("错误1", string(buf[0:n]))
|
||||
c.JSON(http.StatusOK,
|
||||
model.Result{
|
||||
Success: oasis_err.SUCCESS,
|
||||
|
@ -221,3 +225,44 @@ func GetGuideCheck(c *gin.Context) {
|
|||
func PostKillCasaOS(c *gin.Context) {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// @Summary system info
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags sys
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /sys/info [get]
|
||||
func Info(c *gin.Context) {
|
||||
var data = make(map[string]interface{}, 5)
|
||||
|
||||
list := service.MyService.Disk().LSBLK()
|
||||
data["disk"] = list
|
||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
||||
cpuData := make(map[string]interface{})
|
||||
cpuData["percent"] = cpu
|
||||
cpuData["num"] = num
|
||||
data["cpu"] = cpuData
|
||||
data["mem"] = service.MyService.ZiMa().GetMemInfo()
|
||||
|
||||
//拼装网络信息
|
||||
netList := service.MyService.ZiMa().GetNetInfo()
|
||||
newNet := []model.IOCountersStat{}
|
||||
nets := service.MyService.ZiMa().GetNet(true)
|
||||
for _, n := range netList {
|
||||
for _, netCardName := range nets {
|
||||
if n.Name == netCardName {
|
||||
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
|
||||
item.DateTime = time.Now()
|
||||
newNet = append(newNet, item)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data["net"] = newNet
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Summary 获取cpu信息
|
||||
|
@ -83,48 +83,6 @@ func NetInfo(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: newNet})
|
||||
}
|
||||
|
||||
// @Summary 获取信息
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
// @Tags zima
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {string} string "ok"
|
||||
// @Router /zima/getinfo [get]
|
||||
func Info(c *gin.Context) {
|
||||
var data = make(map[string]interface{}, 4)
|
||||
|
||||
var diskArr []*disk.UsageStat
|
||||
diskArr = append(diskArr, service.MyService.ZiMa().GetDiskInfo())
|
||||
data["disk"] = diskArr
|
||||
cpu := service.MyService.ZiMa().GetCpuPercent()
|
||||
num := service.MyService.ZiMa().GetCpuCoreNum()
|
||||
cpuData := make(map[string]interface{})
|
||||
cpuData["percent"] = cpu
|
||||
cpuData["num"] = num
|
||||
data["cpu"] = cpuData
|
||||
data["mem"] = service.MyService.ZiMa().GetMemInfo()
|
||||
|
||||
//拼装网络信息
|
||||
netList := service.MyService.ZiMa().GetNetInfo()
|
||||
newNet := []model.IOCountersStat{}
|
||||
nets := service.MyService.ZiMa().GetNet(true)
|
||||
for _, n := range netList {
|
||||
for _, netCardName := range nets {
|
||||
if n.Name == netCardName {
|
||||
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
|
||||
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
|
||||
item.DateTime = time.Now()
|
||||
newNet = append(newNet, item)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data["net"] = newNet
|
||||
|
||||
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
|
||||
}
|
||||
|
||||
// @Summary 获取信息系统信息
|
||||
// @Produce application/json
|
||||
// @Accept application/json
|
||||
|
|
|
@ -46,7 +46,7 @@ type appStruct struct {
|
|||
//获取我的应用列表
|
||||
func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppList {
|
||||
//获取docker应用
|
||||
cli, err := client2.NewClientWithOpts(client2.FromEnv)
|
||||
cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
|
||||
if err != nil {
|
||||
a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
|
||||
}
|
||||
|
@ -81,13 +81,13 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||
m.Label = m.Title
|
||||
}
|
||||
|
||||
info, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
var tm string
|
||||
if err != nil {
|
||||
tm = time.Now().String()
|
||||
} else {
|
||||
tm = info.State.StartedAt
|
||||
}
|
||||
// info, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
// var tm string
|
||||
// if err != nil {
|
||||
// tm = time.Now().String()
|
||||
// } else {
|
||||
// tm = info.State.StartedAt
|
||||
//}
|
||||
list = append(list, model2.MyAppList{
|
||||
Name: m.Label,
|
||||
Icon: m.Icon,
|
||||
|
@ -95,9 +95,9 @@ func (a *appStruct) GetMyList(index, size int, position bool) *[]model2.MyAppLis
|
|||
CustomId: strings.ReplaceAll(container.Names[0], "/", ""),
|
||||
Port: m.PortMap,
|
||||
Index: m.Index,
|
||||
UpTime: tm,
|
||||
Image: m.Image,
|
||||
Slogan: m.Slogan,
|
||||
//UpTime: tm,
|
||||
Image: m.Image,
|
||||
Slogan: m.Slogan,
|
||||
//Rely: m.Rely,
|
||||
})
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
|
|||
fts.Add("label", "origin=system")
|
||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
|
||||
if err != nil {
|
||||
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
||||
a.log.Error("获取docker容器失败", "app.sys", "line:123", err)
|
||||
}
|
||||
|
||||
//获取本地数据库应用
|
||||
|
@ -179,7 +179,7 @@ func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
|
|||
filters.Add("name", name)
|
||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
|
||||
if err != nil {
|
||||
a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
|
||||
a.log.Error("获取docker容器失败", "app.getcontainerinfo", "line:182", err)
|
||||
}
|
||||
|
||||
if len(containers) > 0 {
|
||||
|
|
|
@ -2,6 +2,7 @@ package service
|
|||
|
||||
import (
|
||||
json2 "encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
type CasaService interface {
|
||||
GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64)
|
||||
GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList)
|
||||
GetServerCategoryList() []model.ServerCategoryList
|
||||
GetTaskList(size int) []model2.TaskDBModel
|
||||
GetServerAppInfo(id string) model.ServerAppList
|
||||
|
@ -44,20 +45,34 @@ func (o *casaService) GetTaskList(size int) []model2.TaskDBModel {
|
|||
return list
|
||||
}
|
||||
|
||||
func (o *casaService) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) {
|
||||
func (o *casaService) GetServerList(index, size, tp, categoryId, key string) (recommend, list, community []model.ServerAppList) {
|
||||
|
||||
keyName := fmt.Sprintf("list_%s_%s_%s_%s", index, size, tp, categoryId)
|
||||
|
||||
if result, ok := Cache.Get(keyName); ok {
|
||||
res, ok := result.(string)
|
||||
if ok {
|
||||
json2.Unmarshal([]byte(gjson.Get(res, "data.list").String()), &list)
|
||||
json2.Unmarshal([]byte(gjson.Get(res, "data.recommend").String()), &recommend)
|
||||
json2.Unmarshal([]byte(gjson.Get(res, "data.community").String()), &community)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
head := make(map[string]string)
|
||||
|
||||
head["Authorization"] = GetToken()
|
||||
|
||||
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/list?index="+index+"&size="+size+"&type="+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, head)
|
||||
|
||||
list := []model.ServerAppList{}
|
||||
json2.Unmarshal([]byte(gjson.Get(listS, "data.list").String()), &list)
|
||||
json2.Unmarshal([]byte(gjson.Get(listS, "data.recommend").String()), &recommend)
|
||||
json2.Unmarshal([]byte(gjson.Get(listS, "data.community").String()), &community)
|
||||
|
||||
count := gjson.Get(listS, "data.count").Int()
|
||||
json2.Unmarshal([]byte(gjson.Get(listS, "data.items").String()), &list)
|
||||
|
||||
return list, count
|
||||
if len(list) > 0 {
|
||||
Cache.SetDefault(keyName, listS)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
|
||||
|
@ -65,7 +80,7 @@ func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
|
|||
head := make(map[string]string)
|
||||
head["Authorization"] = GetToken()
|
||||
|
||||
listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/category", head)
|
||||
listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head)
|
||||
|
||||
list := []model.ServerCategoryList{}
|
||||
|
||||
|
@ -79,7 +94,7 @@ func (o *casaService) GetServerAppInfo(id string) model.ServerAppList {
|
|||
|
||||
head["Authorization"] = GetToken()
|
||||
|
||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/info/"+id, head)
|
||||
infoS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/info/"+id, head)
|
||||
|
||||
info := model.ServerAppList{}
|
||||
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
|
@ -26,7 +27,10 @@ type DiskService interface {
|
|||
AddPartition(path string) string
|
||||
GetDiskInfoByPath(path string) *disk.UsageStat
|
||||
MountDisk(path, volume string)
|
||||
SerialAll(mountPoint string) *[]model2.SerialDisk
|
||||
GetSerialAll() []model2.SerialDisk
|
||||
SaveMountPoint(m model2.SerialDisk)
|
||||
DeleteMountPoint(path, mountPoint string)
|
||||
DeleteMount(id string)
|
||||
}
|
||||
type diskService struct {
|
||||
log loger2.OLog
|
||||
|
@ -86,9 +90,21 @@ func (d *diskService) GetDiskInfoByPath(path string) *disk.UsageStat {
|
|||
|
||||
//get disk details
|
||||
func (d *diskService) LSBLK() []model.LSBLKModel {
|
||||
key := "system_lsblk"
|
||||
|
||||
var n []model.LSBLKModel
|
||||
|
||||
if result, ok := Cache.Get(key); ok {
|
||||
|
||||
res, ok := result.([]model.LSBLKModel)
|
||||
if ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
str := command2.ExecLSBLK()
|
||||
if str == nil {
|
||||
d.log.Error("lsblk exec error")
|
||||
d.log.Error("lsblk exec error,lsblk")
|
||||
return nil
|
||||
}
|
||||
var m []model.LSBLKModel
|
||||
|
@ -97,8 +113,6 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||
d.log.Error("json ummarshal error", err)
|
||||
}
|
||||
|
||||
var n []model.LSBLKModel
|
||||
|
||||
var c []model.LSBLKModel
|
||||
|
||||
var fsused uint64
|
||||
|
@ -136,13 +150,16 @@ func (d *diskService) LSBLK() []model.LSBLKModel {
|
|||
fsused = 0
|
||||
}
|
||||
}
|
||||
if len(n) > 0 {
|
||||
Cache.Add(key, n, time.Second*10)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
|
||||
str := command2.ExecLSBLKByPath(path)
|
||||
if str == nil {
|
||||
d.log.Error("lsblk exec error")
|
||||
d.log.Error("lsblk exec error,str")
|
||||
return model.LSBLKModel{}
|
||||
}
|
||||
var ml []model.LSBLKModel
|
||||
|
@ -197,13 +214,25 @@ func (d *diskService) MountDisk(path, volume string) {
|
|||
}
|
||||
|
||||
func (d *diskService) SaveMountPoint(m model2.SerialDisk) {
|
||||
d.db.Save(&m)
|
||||
d.db.Create(&m)
|
||||
}
|
||||
|
||||
func (d *diskService) SerialAll(mountPoint string) *[]model2.SerialDisk {
|
||||
func (d *diskService) DeleteMount(id string) {
|
||||
|
||||
d.db.Delete(&model2.SerialDisk{}).Where("id = ?", id)
|
||||
}
|
||||
|
||||
func (d *diskService) DeleteMountPoint(path, mountPoint string) {
|
||||
|
||||
d.db.Delete(&model2.SerialDisk{}).Where("path= ? && mount_point = ?", path, mountPoint)
|
||||
|
||||
command2.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;do_umount " + path)
|
||||
}
|
||||
|
||||
func (d *diskService) GetSerialAll() []model2.SerialDisk {
|
||||
var m []model2.SerialDisk
|
||||
d.db.Find(&m)
|
||||
return &m
|
||||
return m
|
||||
}
|
||||
|
||||
func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
json2 "encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"syscall"
|
||||
|
||||
model2 "github.com/IceWhaleTech/CasaOS/service/model"
|
||||
|
@ -366,11 +365,11 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
|
|||
// if net != "host" {
|
||||
// portMaps[nat.Port(fmt.Sprint(m.Port)+"/tcp")] = []nat.PortBinding{{HostIP: "", HostPort: m.PortMap}}
|
||||
// }
|
||||
port := ""
|
||||
//port := ""
|
||||
for _, portMap := range m.Ports {
|
||||
if portMap.CommendPort == m.PortMap && portMap.Protocol == "tcp" || portMap.Protocol == "both" {
|
||||
port = portMap.ContainerPort
|
||||
}
|
||||
// if portMap.CommendPort == m.PortMap && portMap.Protocol == "tcp" || portMap.Protocol == "both" {
|
||||
// port = portMap.ContainerPort
|
||||
// }
|
||||
if portMap.Protocol == "tcp" {
|
||||
|
||||
tContainer, _ := strconv.Atoi(portMap.ContainerPort)
|
||||
|
@ -413,7 +412,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
|
|||
var envArr []string
|
||||
for _, e := range m.Envs {
|
||||
if strings.HasPrefix(e.Value, "$") {
|
||||
envArr = append(envArr, e.Name+"="+env_helper.ReplaceDefaultENV(e.Value))
|
||||
envArr = append(envArr, e.Name+"="+env_helper.ReplaceDefaultENV(e.Value, MyService.System().GetTimeZone()))
|
||||
continue
|
||||
}
|
||||
if len(e.Value) > 0 {
|
||||
|
@ -443,27 +442,28 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
|
|||
for _, v := range m.Volumes {
|
||||
path := v.Path
|
||||
if len(path) == 0 {
|
||||
path = docker.GetDir(containerDbId, v.ContainerPath)
|
||||
path = docker.GetDir(containerDbId, v.Path)
|
||||
if len(path) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
path = strings.ReplaceAll(path, "$AppID", containerDbId)
|
||||
reg1 := regexp.MustCompile(`([^<>/\\\|:""\*\?]+\.\w+$)`)
|
||||
result1 := reg1.FindAllStringSubmatch(path, -1)
|
||||
if len(result1) == 0 {
|
||||
err = file.IsNotExistMkDir(path)
|
||||
if err != nil {
|
||||
ds.log.Error("mkdir error", err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
err = file.IsNotExistCreateFile(path)
|
||||
if err != nil {
|
||||
ds.log.Error("mkdir error", err)
|
||||
continue
|
||||
}
|
||||
//reg1 := regexp.MustCompile(`([^<>/\\\|:""\*\?]+\.\w+$)`)
|
||||
//result1 := reg1.FindAllStringSubmatch(path, -1)
|
||||
//if len(result1) == 0 {
|
||||
err = file.IsNotExistMkDir(path)
|
||||
if err != nil {
|
||||
ds.log.Error("mkdir error", err)
|
||||
continue
|
||||
}
|
||||
//}
|
||||
// else {
|
||||
// err = file.IsNotExistCreateFile(path)
|
||||
// if err != nil {
|
||||
// ds.log.Error("mkdir error", err)
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
|
||||
volumes = append(volumes, mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
|
@ -479,17 +479,17 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
|
|||
if len(m.Restart) > 0 {
|
||||
rp.Name = m.Restart
|
||||
}
|
||||
healthTest := []string{}
|
||||
if len(port) > 0 {
|
||||
healthTest = []string{"CMD-SHELL", "curl -f http://localhost:" + port + m.Index + " || exit 1"}
|
||||
}
|
||||
// healthTest := []string{}
|
||||
// if len(port) > 0 {
|
||||
// healthTest = []string{"CMD-SHELL", "curl -f http://localhost:" + port + m.Index + " || exit 1"}
|
||||
// }
|
||||
|
||||
health := &container.HealthConfig{
|
||||
Test: healthTest,
|
||||
StartPeriod: 0,
|
||||
Retries: 1000,
|
||||
}
|
||||
fmt.Print(health)
|
||||
// health := &container.HealthConfig{
|
||||
// Test: healthTest,
|
||||
// StartPeriod: 0,
|
||||
// Retries: 1000,
|
||||
// }
|
||||
// fmt.Print(health)
|
||||
config := &container.Config{
|
||||
Image: imageName,
|
||||
Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin},
|
||||
|
|
85
service/file.go
Normal file
85
service/file.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
)
|
||||
|
||||
// type InteruptReader struct {
|
||||
// r io.Reader
|
||||
// interupt chan int
|
||||
// }
|
||||
|
||||
// func NewInteruptReader(r io.Reader) InteruptReader {
|
||||
// return InteruptReader{
|
||||
// r,
|
||||
// make(chan int),
|
||||
// }
|
||||
// }
|
||||
|
||||
// func (r InteruptReader) Read(p []byte) (n int, err error) {
|
||||
// if r.r == nil {
|
||||
// return 0, io.EOF
|
||||
// }
|
||||
// select {
|
||||
// case <-r.interupt:
|
||||
// return r.r.Read(p)
|
||||
// default:
|
||||
// r.r = nil
|
||||
// return 0, io.EOF
|
||||
// }
|
||||
// }
|
||||
|
||||
// func (r InteruptReader) Cancel() {
|
||||
// r.interupt <- 0
|
||||
// }
|
||||
|
||||
type reader struct {
|
||||
ctx context.Context
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// NewReader wraps an io.Reader to handle context cancellation.
|
||||
//
|
||||
// Context state is checked BEFORE every Read.
|
||||
func NewReader(ctx context.Context, r io.Reader) io.Reader {
|
||||
if r, ok := r.(*reader); ok && ctx == r.ctx {
|
||||
return r
|
||||
}
|
||||
return &reader{ctx: ctx, r: r}
|
||||
}
|
||||
|
||||
func (r *reader) Read(p []byte) (n int, err error) {
|
||||
select {
|
||||
case <-r.ctx.Done():
|
||||
return 0, r.ctx.Err()
|
||||
default:
|
||||
return r.r.Read(p)
|
||||
}
|
||||
}
|
||||
|
||||
type writer struct {
|
||||
ctx context.Context
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
type copier struct {
|
||||
writer
|
||||
}
|
||||
|
||||
func NewWriter(ctx context.Context, w io.Writer) io.Writer {
|
||||
if w, ok := w.(*copier); ok && ctx == w.ctx {
|
||||
return w
|
||||
}
|
||||
return &copier{writer{ctx: ctx, w: w}}
|
||||
}
|
||||
|
||||
// Write implements io.Writer, but with context awareness.
|
||||
func (w *writer) Write(p []byte) (n int, err error) {
|
||||
select {
|
||||
case <-w.ctx.Done():
|
||||
return 0, w.ctx.Err()
|
||||
default:
|
||||
return w.w.Write(p)
|
||||
}
|
||||
}
|
81
service/file_test.go
Normal file
81
service/file_test.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ctx context.Context
|
||||
var cancel context.CancelFunc
|
||||
|
||||
func TestNewInteruptReader(t *testing.T) {
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
|
||||
go func() {
|
||||
// 在初始上下文的基础上创建一个有取消功能的上下文
|
||||
// ctx, cancel := context.WithCancel(ctx)
|
||||
fmt.Println("开始")
|
||||
fIn, err := os.Open("/Users/liangjianli/Downloads/demo_data.tar.gz")
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
defer fIn.Close()
|
||||
fmt.Println("创建新文件")
|
||||
fOut, err := os.Create("/Users/liangjianli/Downloads/demo_data1.tar.gz")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
defer fOut.Close()
|
||||
|
||||
fmt.Println("准备复制")
|
||||
// _, err = io.Copy(out, NewReader(ctx, f))
|
||||
// time.Sleep(time.Second * 2)
|
||||
//ctx.Done()
|
||||
// cancel()
|
||||
|
||||
// interrupt context after 500ms
|
||||
|
||||
// interrupt context with SIGTERM (CTRL+C)
|
||||
//sigs := make(chan os.Signal, 1)
|
||||
//signal.Notify(sigs, os.Interrupt)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Reader that fails when context is canceled
|
||||
in := NewReader(ctx, fIn)
|
||||
// Writer that fails when context is canceled
|
||||
out := NewWriter(ctx, fOut)
|
||||
|
||||
//time.Sleep(2 * time.Second)
|
||||
|
||||
//cancel()
|
||||
|
||||
n, err := io.Copy(out, in)
|
||||
log.Println(n, "bytes copied.")
|
||||
if err != nil {
|
||||
fmt.Println("Err:", err)
|
||||
}
|
||||
|
||||
fmt.Println("Closing.")
|
||||
}()
|
||||
|
||||
go func() {
|
||||
//<-sigs
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("退出")
|
||||
ddd()
|
||||
}()
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
|
||||
func ddd() {
|
||||
cancel()
|
||||
}
|
|
@ -3,7 +3,7 @@ package model
|
|||
//SerialAdvanced Technology Attachment (STAT)
|
||||
type SerialDisk struct {
|
||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||
DiskId string `json:"disk_id"`
|
||||
Serial string `json:"serial"`
|
||||
Path string `json:"path"`
|
||||
State int `json:"state"`
|
||||
MountPoint string `json:"mount_point"`
|
||||
|
|
|
@ -16,6 +16,7 @@ type SystemService interface {
|
|||
GetCasaOSLogs(lineNumber int) string
|
||||
UpdateAssist()
|
||||
UpSystemPort(port string)
|
||||
GetTimeZone() string
|
||||
}
|
||||
type systemService struct {
|
||||
log loger.OLog
|
||||
|
@ -30,6 +31,11 @@ func (s *systemService) UpdateSystemVersion(version string) {
|
|||
func (s *systemService) UpdateAssist() {
|
||||
s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/assist.sh"))
|
||||
}
|
||||
|
||||
func (s *systemService) GetTimeZone() string {
|
||||
return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetTimeZone")
|
||||
}
|
||||
|
||||
func (s *systemService) GetSystemConfigDebug() []string {
|
||||
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetSysInfo")
|
||||
}
|
||||
|
|
100
shell/helper.sh
100
shell/helper.sh
|
@ -30,6 +30,11 @@ GetNetCard() {
|
|||
fi
|
||||
}
|
||||
|
||||
|
||||
GetTimeZone(){
|
||||
timedatectl | grep "Time zone" | awk '{print $3}'
|
||||
}
|
||||
|
||||
#查看网卡状态
|
||||
#param 网卡名称
|
||||
CatNetCardState() {
|
||||
|
@ -194,7 +199,7 @@ do_mount() {
|
|||
eval $(blkid -o udev ${DEVICE} | grep -i -e "ID_FS_LABEL" -e "ID_FS_TYPE")
|
||||
|
||||
LABEL=$2
|
||||
if grep -q " /media/${LABEL} " /etc/mtab; then
|
||||
if grep -q " ${LABEL} " /etc/mtab; then
|
||||
# Already in use, make a unique one
|
||||
LABEL+="-${DEVBASE}"
|
||||
fi
|
||||
|
@ -205,7 +210,7 @@ do_mount() {
|
|||
DEV_LABEL="${DEVBASE}"
|
||||
fi
|
||||
|
||||
MOUNT_POINT="/media/${DEV_LABEL}"
|
||||
MOUNT_POINT="${DEV_LABEL}"
|
||||
|
||||
${log} "Mount point: ${MOUNT_POINT}"
|
||||
|
||||
|
@ -233,3 +238,94 @@ do_mount() {
|
|||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# $1=sda1
|
||||
do_umount() {
|
||||
log="logger -t usb-mount.sh -s "
|
||||
DEVBASE=$1
|
||||
DEVICE="${DEVBASE}"
|
||||
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
||||
|
||||
if [[ -z ${MOUNT_POINT} ]]; then
|
||||
${log} "Warning: ${DEVICE} is not mounted"
|
||||
else
|
||||
umount -l ${DEVICE}
|
||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
||||
/bin/rmdir "${MOUNT_POINT}"
|
||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
||||
fi
|
||||
|
||||
}
|
||||
# $1=/mnt/volume1/data.img
|
||||
# $2=100G
|
||||
PackageDocker() {
|
||||
image=$1
|
||||
docker="/mnt/casa_docker"
|
||||
#判断目录docker存在不存在则创建,存在检查是否为空
|
||||
|
||||
if [ ! -d "$docker" ]; then
|
||||
mkdir ${docker}
|
||||
fi
|
||||
|
||||
if [ "$(ls -A $docker)" = "" ]; then
|
||||
echo "$docker count is 0"
|
||||
else
|
||||
mkdir ${docker}_bak
|
||||
mv -r ${docker} ${docker}_bak
|
||||
fi
|
||||
|
||||
daemon="/etc/docker/daemon.json"
|
||||
#1创建img文件在挂载的目录
|
||||
fallocate -l $2 $image
|
||||
#2初始化img文件
|
||||
mkfs -t ext4 $image
|
||||
#3挂载img文件
|
||||
sudo mount -o loop $image $docker
|
||||
#4给移动/var/lib/docker数据到img挂载的目录
|
||||
systemctl stop docker.socket
|
||||
systemctl stop docker
|
||||
cp -r /var/lib/docker/* ${docker}/
|
||||
#5在/etc/docker写入daemon.json(需要检查)
|
||||
if [ -d "$daemon" ]; then
|
||||
mv -r $daemon ${daemon}.bak
|
||||
fi
|
||||
echo "{\"data-root\": \"$docker\"}" >$daemon
|
||||
#删除老数据腾出空间
|
||||
#rm -fr /var/lib/docker
|
||||
systemctl start docker.socket
|
||||
systemctl start docker
|
||||
}
|
||||
|
||||
DockerImgMove() {
|
||||
image=$1
|
||||
systemctl stop docker.socket
|
||||
systemctl stop docker
|
||||
sudo umount -f $image
|
||||
}
|
||||
|
||||
GetDockerDataRoot() {
|
||||
docker info | grep "Docker Root Dir:"
|
||||
}
|
||||
|
||||
SetLink() {
|
||||
ln -s /mnt/casa_sda1/AppData /DATA/AppData
|
||||
#删除所有软链
|
||||
find /DATA -type l -delete
|
||||
}
|
||||
|
||||
#压缩文件夹
|
||||
|
||||
TarFolder() {
|
||||
#压缩
|
||||
tar -zcvf data.tar.gz -C/DATA/ AppDataBak/
|
||||
|
||||
#解压
|
||||
tar zxvf data.tar.gz
|
||||
|
||||
#查看某文件夹下的所有包括子文件夹文件
|
||||
ls /DATA/Media -lR | grep "^-" | wc -l
|
||||
# ls -lR|grep "^d"| wc -l 查看某个文件夹下文件夹的个数,包括子文件夹下的文件夹个数。
|
||||
|
||||
#查看固定文件夹大小
|
||||
du -sh /DATA
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
|
||||
const CURRENTVERSION = "0.2.3"
|
||||
const BODY = "<li>Add detailed CPU and memory statistics.</li><li>Add the multi-language function and add Chinese translation.</li><li>Add the function to modify the search engine.</li><li>Add the function of modifying the WebUI port</li><li>fixed some bugs</li><li>Preprocessing usb automounting</li><li>Update update script</li>"
|
||||
const CURRENTVERSION = "0.2.4"
|
||||
const BODY = "<li>New App Store</li><li>Fix minor bugs</li>"
|
||||
|
|
Loading…
Reference in a new issue