Преглед на файлове

New App Store

Add App Store for installation
Fix favicon display in dark mode
link преди 3 години
родител
ревизия
a5fee0ee97
променени са 18 файла, в които са добавени 224 реда и са изтрити 147 реда
  1. 1 1
      UI
  2. 29 26
      model/app.go
  3. 21 15
      model/manifest.go
  4. 18 3
      pkg/docker/volumes.go
  5. 10 0
      pkg/docker/volumes_test.go
  6. 19 0
      pkg/utils/env_helper/env.go
  7. 1 0
      pkg/utils/port/port.go
  8. 2 1
      pkg/utils/sort/app_info_evn.go
  9. 52 35
      route/v1/app.go
  10. 14 7
      route/v1/docker.go
  11. 6 31
      service/app.go
  12. 20 7
      service/casa.go
  13. 3 2
      service/disk.go
  14. 21 13
      service/docker.go
  15. 1 1
      service/docker_base/common.go
  16. 1 0
      service/model/o_notify.go
  17. 3 3
      service/service.go
  18. 2 2
      types/system.go

+ 1 - 1
UI

@@ -1 +1 @@
-Subproject commit fff9cdeb483d4d01d106641eb1a1c266fd7aa19b
+Subproject commit 4fe7dc775653c7b853cf3b98857b23225d6e1f22

+ 29 - 26
model/app.go

@@ -7,32 +7,35 @@ import (
 )
 
 type ServerAppList struct {
-	Id             uint       `gorm:"column:id;primary_key" json:"id"`
-	Title          string     `json:"title"`
-	Description    string     `json:"description"`
-	Tagline        string     `json:"tagline"`
-	Tags           Strings    `gorm:"type:json" json:"tags"`
-	Icon           string     `json:"icon"`
-	ScreenshotLink Strings    `gorm:"type:json" json:"screenshot_link"`
-	Category       string     `json:"category"`
-	TcpPort        uint       `json:"tcp_port"`
-	PortMap        uint       `json:"port_map"`
-	ImageVersion   string     `json:"image_version"`
-	Tip            string     `json:"tip"`
-	Configures     configures `gorm:"type:json" json:"configures"`
-	NetworkModel   string     `json:"network_mode"`
-	Image          string     `json:"image"`
-	Index          string     `json:"index"`
-	CreatedAt      time.Time  `json:"created_at"`
-	UpdatedAt      time.Time  `json:"updated_at"`
-	State          string     `json:"state"`
-	Author         string     `json:"author"`
-	MinMemory      int        `json:"min_memory"`
-	MinDisk        int        `json:"min_disk"`
-	MaxMemory      uint64     `json:"max_memory"`
-	Thumbnail      string     `json:"thumbnail"`
-	Healthy        string     `json:"healthy"`
-	Plugins        Strings    `json:"plugins"`
+	Id             uint      `gorm:"column:id;primary_key" json:"id"`
+	Title          string    `json:"title"`
+	Description    string    `json:"description"`
+	Tagline        string    `json:"tagline"`
+	Tags           Strings   `gorm:"type:json" json:"tags"`
+	Icon           string    `json:"icon"`
+	ScreenshotLink Strings   `gorm:"type:json" json:"screenshot_link"`
+	Category       string    `json:"category"`
+	PortMap        string    `json:"port_map"`
+	ImageVersion   string    `json:"image_version"`
+	Tip            string    `json:"tip"`
+	Envs           EnvArray  `json:"envs"`
+	Ports          PortArray `json:"ports"`
+	Volumes        PathArray `json:"volumes"`
+	Devices        PathArray `json:"devices"`
+	NetworkModel   string    `json:"network_model"`
+	Image          string    `json:"image"`
+	Index          string    `json:"index"`
+	CreatedAt      time.Time `json:"created_at"`
+	UpdatedAt      time.Time `json:"updated_at"`
+	State          string    `json:"state"`
+	Author         string    `json:"author"`
+	MinMemory      int       `json:"min_memory"`
+	MinDisk        int       `json:"min_disk"`
+	MaxMemory      uint64    `json:"max_memory"`
+	Thumbnail      string    `json:"thumbnail"`
+	Healthy        string    `json:"healthy"`
+	Plugins        Strings   `json:"plugins"`
+	Origin         string    `json:"origin"`
 }
 
 type Ports struct {

+ 21 - 15
model/manifest.go

@@ -17,20 +17,22 @@ type UdpPorts struct {
 /*******************使用gorm支持json************************************/
 
 type PortMap struct {
-	ContainerPort string `json:"container,omitempty"`
-	CommendPort   string `json:"host,omitempty"`
+	ContainerPort string `json:"container"`
+	CommendPort   string `json:"host"`
 	Protocol      string `json:"protocol"`
+	Desc          string `json:"desc"`
+	Type          int    `json:"type"`
 }
 
-type PortArrey []PortMap
+type PortArray []PortMap
 
 // Value 实现方法
-func (p PortArrey) Value() (driver.Value, error) {
+func (p PortArray) Value() (driver.Value, error) {
 	return json.Marshal(p)
 }
 
 // Scan 实现方法
-func (p *PortArrey) Scan(input interface{}) error {
+func (p *PortArray) Scan(input interface{}) error {
 	return json.Unmarshal(input.([]byte), p)
 }
 
@@ -41,20 +43,22 @@ func (p *PortArrey) Scan(input interface{}) error {
 type Env struct {
 	Name  string `json:"container"`
 	Value string `json:"host"`
+	Desc  string `json:"desc"`
+	Type  int    `json:"type"`
 }
 
 type JSON json.RawMessage
 
-type EnvArrey []Env
+type EnvArray []Env
 
 // Value 实现方法
-func (p EnvArrey) Value() (driver.Value, error) {
+func (p EnvArray) Value() (driver.Value, error) {
 	return json.Marshal(p)
 	//return .MarshalJSON()
 }
 
 // Scan 实现方法
-func (p *EnvArrey) Scan(input interface{}) error {
+func (p *EnvArray) Scan(input interface{}) error {
 	return json.Unmarshal(input.([]byte), p)
 }
 
@@ -65,17 +69,19 @@ func (p *EnvArrey) Scan(input interface{}) error {
 type PathMap struct {
 	ContainerPath string `json:"container"`
 	Path          string `json:"host"`
+	Type          int    `json:"type"`
+	Desc          string `json:"desc"`
 }
 
-type PathArrey []PathMap
+type PathArray []PathMap
 
 // Value 实现方法
-func (p PathArrey) Value() (driver.Value, error) {
+func (p PathArray) Value() (driver.Value, error) {
 	return json.Marshal(p)
 }
 
 // Scan 实现方法
-func (p *PathArrey) Scan(input interface{}) error {
+func (p *PathArray) Scan(input interface{}) error {
 	return json.Unmarshal(input.([]byte), p)
 }
 
@@ -103,10 +109,10 @@ type CustomizationPostData struct {
 	Index        string    `json:"index"`
 	Icon         string    `json:"icon"`
 	Image        string    `json:"image"`
-	Envs         EnvArrey  `json:"envs"`
-	Ports        PortArrey `json:"ports"`
-	Volumes      PathArrey `json:"volumes"`
-	Devices      PathArrey `json:"devices"`
+	Envs         EnvArray  `json:"envs"`
+	Ports        PortArray `json:"ports"`
+	Volumes      PathArray `json:"volumes"`
+	Devices      PathArray `json:"devices"`
 	//Port         string    `json:"port,omitempty"`
 	PortMap     string `json:"port_map"`
 	CpuShares   int64  `json:"cpu_shares"`

+ 18 - 3
pkg/docker/volumes.go

@@ -1,10 +1,25 @@
 package docker
 
+import "strings"
+
 func GetDir(id, envName string) string {
 	var path string
-	switch envName {
-	case "/config":
-		path = "/oasis/app_data/" + id + "/"
+
+	if len(id) == 0 {
+		id = "$AppID"
+	}
+
+	switch {
+	case strings.Contains(strings.ToLower(envName), "config"):
+		path = "/DATA/AppData/" + id + "/"
+	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), "download"):
+		path = "/DATA/Downloads/"
+	case strings.Contains(strings.ToLower(envName), "photo") || strings.Contains(strings.ToLower(envName), "pictures"):
+		path = "/DATA/Downloads/"
 	default:
 		//path = "/media"
 	}

+ 10 - 0
pkg/docker/volumes_test.go

@@ -0,0 +1,10 @@
+package docker
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestGetDir(t *testing.T) {
+	fmt.Println(GetDir("", "config"))
+}

+ 19 - 0
pkg/utils/env_helper/env.go

@@ -0,0 +1,19 @@
+package env_helper
+
+import "strings"
+
+func ReplaceDefaultENV(key string) string {
+	temp := ""
+	switch key {
+	case "$DefaultPassword":
+		temp = "casaos"
+	case "$DefaultUserName":
+		temp = "admin"
+	}
+	return temp
+}
+
+//replace env default setting
+func ReplaceStringDefaultENV(str string) string {
+	return strings.ReplaceAll(strings.ReplaceAll(str, "$DefaultPassword", ReplaceDefaultENV("$DefaultPassword")), "$DefaultUserName", ReplaceDefaultENV("$DefaultUserName"))
+}

+ 1 - 0
pkg/utils/port/port.go

@@ -47,6 +47,7 @@ func IsPortAvailable(port int, t string) bool {
 		uc, err := net.ListenUDP("udp", sadd)
 
 		if err != nil {
+			fmt.Println(err.Error())
 			return false
 		} else {
 			defer uc.Close()

+ 2 - 1
pkg/utils/sort/app_info_evn.go

@@ -1,8 +1,9 @@
 package sort
 
 import (
-	"github.com/IceWhaleTech/CasaOS/model"
 	"sort"
+
+	"github.com/IceWhaleTech/CasaOS/model"
 )
 
 // 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool

+ 52 - 35
route/v1/app.go

@@ -1,15 +1,17 @@
 package v1
 
 import (
+	"net/http"
+	"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"
-	"github.com/IceWhaleTech/CasaOS/pkg/utils/sort"
 	"github.com/IceWhaleTech/CasaOS/service"
 	"github.com/gin-gonic/gin"
-	"net/http"
-	"strconv"
 )
 
 // @Summary 获取远程列表
@@ -110,51 +112,66 @@ func MyAppList(c *gin.Context) {
 func AppInfo(c *gin.Context) {
 
 	id := c.Param("id")
-	info := service.MyService.App().GetServerAppInfo(id)
+	info := service.MyService.OAPI().GetServerAppInfo(id)
 	if info.NetworkModel != "host" {
-		port, _ := port2.GetAvailablePort("tcp")
-		info.PortMap = uint(port)
-		for i := 0; i < len(info.Configures.TcpPorts); i++ {
-			info.Configures.TcpPorts[i].CommendPort, _ = port2.GetAvailablePort("tcp")
-		}
-		for i := 0; i < len(info.Configures.UdpPorts); i++ {
-			info.Configures.UdpPorts[i].CommendPort, _ = port2.GetAvailablePort("udp")
+		for i := 0; i < len(info.Ports); i++ {
+			if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
+				info.Ports[i].CommendPort = strconv.Itoa(p)
+			} else {
+				if info.Ports[i].Protocol == "tcp" {
+					if p, err := port2.GetAvailablePort("tcp"); err == nil {
+						info.Ports[i].CommendPort = strconv.Itoa(p)
+					}
+				} else if info.Ports[i].Protocol == "upd" {
+					if p, err := port2.GetAvailablePort("udp"); err == nil {
+						info.Ports[i].CommendPort = strconv.Itoa(p)
+					}
+				}
+			}
+
+			if info.Ports[i].Type == 0 {
+				info.PortMap = info.Ports[i].CommendPort
+			}
 		}
-	} else {
-		info.PortMap = info.TcpPort
 	}
 
-	for i := 0; i < len(info.Configures.Devices); i++ {
-		if !file.CheckNotExist(info.Configures.Devices[i].ContainerPath) {
-			info.Configures.Devices[i].Path = info.Configures.Devices[i].ContainerPath
+	for i := 0; i < len(info.Devices); i++ {
+		if !file.CheckNotExist(info.Devices[i].ContainerPath) {
+			info.Devices[i].Path = info.Devices[i].ContainerPath
 		}
 	}
-
-	portOrder := func(c1, c2 *model.Ports) bool {
-		return c1.Type < c2.Type
+	if len(info.Tip) > 0 {
+		info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
 	}
 
-	envOrder := func(c1, c2 *model.Envs) bool {
-		return c1.Type < c2.Type
+	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
+	// }
 
-	volOrder := func(c1, c2 *model.Volume) bool {
-		return c1.Type < c2.Type
-	}
+	// envOrder := func(c1, c2 *model.Envs) bool {
+	// 	return c1.Type < c2.Type
+	// }
 
-	devOrder := func(c1, c2 *model.Devices) bool {
-		return c1.Type < c2.Type
-	}
+	// volOrder := func(c1, c2 *model.Volume) bool {
+	// 	return c1.Type < c2.Type
+	// }
 
-	//sort
-	if info.NetworkModel != "host" {
-		sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts)
-		sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts)
-	}
+	// devOrder := func(c1, c2 *model.Devices) bool {
+	// 	return c1.Type < c2.Type
+	// }
 
-	sort.EnvSort(envOrder).Sort(info.Configures.Envs)
-	sort.VolSort(volOrder).Sort(info.Configures.Volumes)
-	sort.DevSort(devOrder).Sort(info.Configures.Devices)
+	//sort
+	// if info.NetworkModel != "host" {
+	// 	sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts)
+	// 	sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts)
+	// }
+
+	// sort.EnvSort(envOrder).Sort(info.Envs)
+	// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
+	// sort.DevSort(devOrder).Sort(info.Devices)
 
 	info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
 

+ 14 - 7
route/v1/docker.go

@@ -25,6 +25,7 @@ import (
 	"github.com/gorilla/websocket"
 	"github.com/jinzhu/copier"
 	uuid "github.com/satori/go.uuid"
+	"github.com/tidwall/gjson"
 	"golang.org/x/crypto/ssh"
 )
 
@@ -172,7 +173,7 @@ func InstallApp(c *gin.Context) {
 		dockerImageVersion = "latest"
 	}
 	if m.Origin != "custom" {
-		appInfo = service.MyService.App().GetServerAppInfo(appId)
+		appInfo = service.MyService.OAPI().GetServerAppInfo(appId)
 
 	} else {
 
@@ -239,6 +240,7 @@ func InstallApp(c *gin.Context) {
 	go func() {
 		installLog := model2.AppNotify{}
 		installLog.State = 0
+		installLog.CustomId = id
 		installLog.Message = "installing rely"
 		installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
 		installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
@@ -282,7 +284,6 @@ func InstallApp(c *gin.Context) {
 					}
 				}
 			}
-
 		}
 
 		installLog.Message = "pulling"
@@ -333,6 +334,8 @@ func InstallApp(c *gin.Context) {
 			service.MyService.Notify().UpdateLog(installLog)
 		}
 
+		//		echo -e "hellow\nworld" >>
+
 		//step:启动容器
 		err = service.MyService.Docker().DockerContainerStart(id)
 		if err != nil {
@@ -685,7 +688,11 @@ func UnInstallApp(c *gin.Context) {
 	if info.Origin != "custom" {
 
 		//step: 删除文件夹
-		service.MyService.App().DelAppConfigDir(appId)
+		vol := gjson.Get(info.Volumes, "#.host")
+		for _, v := range vol.Array() {
+
+			service.MyService.App().DelAppConfigDir(appId, v.String())
+		}
 
 		//step: 删除install log
 		service.MyService.Notify().DelLog(appId)
@@ -1119,16 +1126,16 @@ func ContainerUpdateInfo(c *gin.Context) {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: err.Error()})
 		return
 	}
-	var port model.PortArrey
+	var port model.PortArray
 	json2.Unmarshal([]byte(appInfo.Ports), &port)
 
-	var envs model.EnvArrey
+	var envs model.EnvArray
 	json2.Unmarshal([]byte(appInfo.Envs), &envs)
 
-	var vol model.PathArrey
+	var vol model.PathArray
 	json2.Unmarshal([]byte(appInfo.Volumes), &vol)
 
-	var dir model.PathArrey
+	var dir model.PathArray
 	json2.Unmarshal([]byte(appInfo.Devices), &dir)
 
 	//volumesStr, _ := json2.Marshal(m.Volumes)

+ 6 - 31
service/app.go

@@ -2,35 +2,31 @@ package service
 
 import (
 	"context"
-	json2 "encoding/json"
-	"github.com/IceWhaleTech/CasaOS/model"
+	"strings"
+	"time"
+
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
-	httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	model2 "github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	client2 "github.com/docker/docker/client"
 	"github.com/pkg/errors"
-	"github.com/tidwall/gjson"
 	"gorm.io/gorm"
-	"strings"
-	"time"
 )
 
 type AppService interface {
 	GetMyList(index, size int, position bool) *[]model2.MyAppList
 	SaveContainer(m model2.AppListDBModel)
-	GetServerAppInfo(id string) model.ServerAppList
 	GetUninstallInfo(id string) model2.AppListDBModel
 	RemoveContainerById(id string)
 	GetContainerInfo(name string) (types.Container, error)
 	GetAppDBInfo(id string) model2.AppListDBModel
 	UpdateApp(m model2.AppListDBModel)
 	GetSimpleContainerInfo(name string) (types.Container, error)
-	DelAppConfigDir(id string)
+	DelAppConfigDir(id, path string)
 }
 
 type appStruct struct {
@@ -155,27 +151,6 @@ func (a *appStruct) GetUninstallInfo(id string) model2.AppListDBModel {
 	return m
 }
 
-func (a *appStruct) GetServerAppInfo(id string) model.ServerAppList {
-
-	head := make(map[string]string)
-
-	t := make(chan string)
-
-	go func() {
-		str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
-
-		t <- gjson.Get(str, "data").String()
-	}()
-	head["Authorization"] = <-t
-
-	infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/info/"+id, head)
-
-	info := model.ServerAppList{}
-	json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
-
-	return info
-}
-
 //创建容器成功后保存容器
 func (a *appStruct) SaveContainer(m model2.AppListDBModel) {
 	a.db.Table(model2.CONTAINERTABLENAME).Create(&m)
@@ -185,8 +160,8 @@ func (a *appStruct) UpdateApp(m model2.AppListDBModel) {
 	a.db.Table(model2.CONTAINERTABLENAME).Save(&m)
 }
 
-func (a *appStruct) DelAppConfigDir(id string) {
-	command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;DelAppConfigDir " + docker.GetDir(id, "/config"))
+func (a *appStruct) DelAppConfigDir(id, path string) {
+	command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;DelAppConfigDir " + docker.GetDir(id, path))
 }
 
 func (a *appStruct) RemoveContainerById(id string) {

+ 20 - 7
service/oasis.go → service/casa.go

@@ -11,16 +11,17 @@ import (
 	"github.com/tidwall/gjson"
 )
 
-type OasisService interface {
+type CasaService interface {
 	GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64)
 	GetServerCategoryList() []model.ServerCategoryList
 	GetTaskList(size int) []model2.TaskDBModel
+	GetServerAppInfo(id string) model.ServerAppList
 }
 
-type oasisService struct {
+type casaService struct {
 }
 
-func (o *oasisService) GetTaskList(size int) []model2.TaskDBModel {
+func (o *casaService) GetTaskList(size int) []model2.TaskDBModel {
 	head := make(map[string]string)
 
 	head["Authorization"] = GetToken()
@@ -33,7 +34,7 @@ func (o *oasisService) GetTaskList(size int) []model2.TaskDBModel {
 	return list
 }
 
-func (o *oasisService) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) {
+func (o *casaService) GetServerList(index, size, tp, categoryId, key string) ([]model.ServerAppList, int64) {
 
 	head := make(map[string]string)
 
@@ -49,7 +50,7 @@ func (o *oasisService) GetServerList(index, size, tp, categoryId, key string) ([
 	return list, count
 }
 
-func (o *oasisService) GetServerCategoryList() []model.ServerCategoryList {
+func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
 
 	head := make(map[string]string)
 	head["Authorization"] = GetToken()
@@ -62,7 +63,19 @@ func (o *oasisService) GetServerCategoryList() []model.ServerCategoryList {
 
 	return list
 }
+func (o *casaService) GetServerAppInfo(id string) model.ServerAppList {
 
+	head := make(map[string]string)
+
+	head["Authorization"] = GetToken()
+
+	infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/app/info/"+id, head)
+
+	info := model.ServerAppList{}
+	json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
+
+	return info
+}
 func GetToken() string {
 	t := make(chan string)
 	keyName := "casa_token"
@@ -86,6 +99,6 @@ func GetToken() string {
 	return auth
 }
 
-func NewOasisService() OasisService {
-	return &oasisService{}
+func NewOasisService() CasaService {
+	return &casaService{}
 }

+ 3 - 2
service/disk.go

@@ -3,14 +3,15 @@ package service
 import (
 	json2 "encoding/json"
 	"fmt"
+	"strconv"
+	"strings"
+
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/tidwall/gjson"
-	"strconv"
-	"strings"
 )
 
 type DiskService interface {

+ 21 - 13
service/docker.go

@@ -20,6 +20,7 @@ import (
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 
@@ -60,6 +61,7 @@ type DockerService interface {
 	DockerNetworkModelList() []types.NetworkResource
 	DockerImageInfo(image string)
 	GetNetWorkNameByNetWorkID(id string) (string, error)
+	ContainerExecShell(container_id string) string
 }
 
 type dockerService struct {
@@ -67,15 +69,20 @@ type dockerService struct {
 	log     loger2.OLog
 }
 
-func DockerPs() {
+func (ds *dockerService) ContainerExecShell(container_id string) string {
 	cli, _ := client2.NewClientWithOpts(client2.FromEnv)
-	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
+	exec, err := cli.ContainerExecCreate(context.Background(), container_id, types.ExecConfig{
+		User: "1000:1000",
+		Cmd:  []string{"echo -e \"hellow\nworld\" >> /a.txt"},
+	})
 	if err != nil {
 		os.Exit(5)
 	}
-	for _, container := range containers {
-		fmt.Printf("%s %s\n", container.ID[:10], container.Image)
+	err = cli.ContainerExecStart(context.Background(), exec.ID, types.ExecStartCheck{})
+	if err != nil {
+		fmt.Println("exec script error ", err)
 	}
+	return exec.ID
 }
 
 //创建默认网络
@@ -401,6 +408,10 @@ 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))
+			continue
+		}
 		if len(e.Value) > 0 {
 			if e.Value == "port_map" {
 				envArr = append(envArr, e.Name+"="+m.PortMap)
@@ -433,6 +444,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
 				continue
 			}
 		}
+		path = strings.ReplaceAll(path, "$AppID", containerDbId)
 		reg1 := regexp.MustCompile(`([^<>/\\\|:""\*\?]+\.\w+$)`)
 		result1 := reg1.FindAllStringSubmatch(path, -1)
 		if len(result1) == 0 {
@@ -475,11 +487,12 @@ func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId s
 		StartPeriod: 0,
 		Retries:     1000,
 	}
+	fmt.Print(health)
 	config := &container.Config{
-		Image:       imageName,
-		Labels:      map[string]string{"origin": m.Origin, m.Origin: m.Origin},
-		Env:         envArr,
-		Healthcheck: health,
+		Image:  imageName,
+		Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin},
+		Env:    envArr,
+		//	Healthcheck: health,
 	}
 	hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net)}
 	//if net != "host" {
@@ -816,7 +829,6 @@ func Containerd() {
 	)
 
 	if err != nil {
-		fmt.Println("333")
 		fmt.Println(err)
 	}
 	defer container.Delete(ctx, containerd.WithSnapshotCleanup)
@@ -824,7 +836,6 @@ func Containerd() {
 	// create a task from the container
 	task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
 	if err != nil {
-		fmt.Println("444")
 		fmt.Println(err)
 	}
 	defer task.Delete(ctx)
@@ -837,7 +848,6 @@ func Containerd() {
 
 	// call start on the task to execute the redis server
 	if err = task.Start(ctx); err != nil {
-		fmt.Println("555")
 		fmt.Println(err)
 	}
 
@@ -847,7 +857,6 @@ func Containerd() {
 
 	// kill the process and get the exit status
 	if err = task.Kill(ctx, syscall.SIGTERM); err != nil {
-		fmt.Println("666")
 		fmt.Println(err)
 	}
 
@@ -856,7 +865,6 @@ func Containerd() {
 	status := <-exitStatusC
 	code, _, err := status.Result()
 	if err != nil {
-		fmt.Println("777")
 		fmt.Println(err)
 	}
 	fmt.Printf("redis-server exited with status: %d\n", code)

+ 1 - 1
service/docker_base/common.go

@@ -3,7 +3,7 @@ package docker_base
 import "github.com/IceWhaleTech/CasaOS/model"
 
 //过滤mysql关键字
-func MysqlFilter(c MysqlConfig, envs model.EnvArrey) model.EnvArrey {
+func MysqlFilter(c MysqlConfig, envs model.EnvArray) model.EnvArray {
 	for i := 0; i < len(envs); i++ {
 		switch envs[i].Value {
 		case "$MYSQL_HOST":

+ 1 - 0
service/model/o_notify.go

@@ -9,6 +9,7 @@ type AppNotify struct {
 	Type      int    `json:"type"` // 1:显示即为已读 2:info 3:warning 4:error 5:success
 	Icon      string `json:"icon"`
 	Name      string `json:"name"`
+	CustomId  string `gorm:"column:custom_id;primary_key" json:"custom_id"`
 }
 
 func (p *AppNotify) TableName() string {

+ 3 - 3
service/service.go

@@ -18,7 +18,7 @@ type Repository interface {
 	//Redis() RedisService
 	ZeroTier() ZeroTierService
 	ZiMa() ZiMaService
-	OAPI() OasisService
+	OAPI() CasaService
 	Disk() DiskService
 	Notify() NotifyServer
 	ShareDirectory() ShareDirService
@@ -58,7 +58,7 @@ type store struct {
 	docker         DockerService
 	zerotier       ZeroTierService
 	zima           ZiMaService
-	oapi           OasisService
+	oapi           CasaService
 	disk           DiskService
 	notify         NotifyServer
 	shareDirectory ShareDirService
@@ -105,7 +105,7 @@ func (c *store) ZeroTier() ZeroTierService {
 func (c *store) ZiMa() ZiMaService {
 	return c.zima
 }
-func (c *store) OAPI() OasisService {
+func (c *store) OAPI() CasaService {
 	return c.oapi
 }
 

+ 2 - 2
types/system.go

@@ -1,4 +1,4 @@
 package types
 
-const CURRENTVERSION = "0.1.9"
-const BODY = "<li>add casaOS logs</li><li>add application  terminal</li><li>add application  logs</li>"
+const CURRENTVERSION = "0.1.10"
+const BODY = "<li>Add App Store for installation</li><li>add casaOS logs</li><li>add application  terminal</li><li>add application  logs</li>"