Skip to content

Commit

Permalink
Fixing bugs
Browse files Browse the repository at this point in the history
Resolve application installation path errors
  • Loading branch information
LinkLeong committed Nov 9, 2021
1 parent 3713096 commit f020c11
Show file tree
Hide file tree
Showing 15 changed files with 327 additions and 24 deletions.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func init() {
//gredis.GetRedisConn(config.RedisInfo),
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
service.Cache = cache.Init()
route.InitFunction()
}

// @title casaOS API
Expand Down
2 changes: 2 additions & 0 deletions model/sys_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ type SystemConfig struct {
ConfigStr string `json:"config_str"`
WidgetList string `json:"widget_list"`
ConfigPath string `json:"config_path"`
SyncPort string `json:"sync_port"`
SyncKey string `json:"sync_key"`
}
8 changes: 8 additions & 0 deletions model/system_app/sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package system_app

import "encoding/xml"

type SyncConfig struct {
XMLName xml.Name `xml:"configuration"`
Key string `xml:"gui>apikey"`
}
6 changes: 5 additions & 1 deletion pkg/docker/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ func GetDir(id, envName string) string {
}

switch {
case strings.Contains(strings.ToLower(envName), "config"):
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), "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/"
default:
//path = "/media"
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/utils/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,16 @@ func IsNotExistCreateFile(src string) error {

return nil
}

func ReadFullFile(path string) []byte {
file, err := os.Open(path)
if err != nil {
return []byte("")
}
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil {
return []byte("")
}
return content
}
188 changes: 188 additions & 0 deletions route/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package route

import (
"encoding/json"
"encoding/xml"
"strconv"
"time"

"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/model/system_app"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/docker"
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
"github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
uuid "github.com/satori/go.uuid"
)

func InitFunction() {
go checkSystemApp()
}

var syncIsExistence = false

func installSyncthing(appId string) {

var appInfo model.ServerAppList
m := model.CustomizationPostData{}
var dockerImage string
var dockerImageVersion string

appInfo = service.MyService.OAPI().GetServerAppInfo(appId)

dockerImage = appInfo.Image

if len(appInfo.ImageVersion) == 0 {
dockerImageVersion = "latest"
}

if appInfo.NetworkModel != "host" {
for i := 0; i < len(appInfo.Ports); i++ {
if p, _ := strconv.Atoi(appInfo.Ports[i].ContainerPort); port.IsPortAvailable(p, appInfo.Ports[i].Protocol) {
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
} else {
if appInfo.Ports[i].Protocol == "tcp" {
if p, err := port.GetAvailablePort("tcp"); err == nil {
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
}
} else if appInfo.Ports[i].Protocol == "upd" {
if p, err := port.GetAvailablePort("udp"); err == nil {
appInfo.Ports[i].CommendPort = strconv.Itoa(p)
}
}
}

if appInfo.Ports[i].Type == 0 {
appInfo.PortMap = appInfo.Ports[i].CommendPort
}
}
}

for i := 0; i < len(appInfo.Devices); i++ {
if !file.CheckNotExist(appInfo.Devices[i].ContainerPath) {
appInfo.Devices[i].Path = appInfo.Devices[i].ContainerPath
}
}
if len(appInfo.Tip) > 0 {
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()

installLog := model2.AppNotify{}

// step:下载镜像
err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
if err != nil {
//pull image error
return
}

for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) {
time.Sleep(time.Second)
}

m.CpuShares = 50
m.Envs = appInfo.Envs
m.Memory = int64(appInfo.MaxMemory)
m.Origin = "system"
m.PortMap = appInfo.PortMap
m.Ports = appInfo.Ports
m.Restart = ""
m.Volumes = appInfo.Volumes

containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel)

if err != nil {
// create container error
return
}

//step:start container
err = service.MyService.Docker().DockerContainerStart(id)
if err != nil {
//start container error
return
}

portsStr, _ := json.Marshal(appInfo.Ports)
envsStr, _ := json.Marshal(appInfo.Envs)
volumesStr, _ := json.Marshal(appInfo.Volumes)
devicesStr, _ := json.Marshal(appInfo.Devices)
//step: 保存数据到数据库
md := model2.AppListDBModel{
CustomId: id,
Title: appInfo.Title,
//ScreenshotLink: appInfo.ScreenshotLink,
Slogan: appInfo.Tagline,
Description: appInfo.Description,
//Tags: appInfo.Tags,
Icon: appInfo.Icon,
Version: dockerImageVersion,
ContainerId: containerId,
Image: dockerImage,
Index: appInfo.Index,
PortMap: appInfo.PortMap,
Label: appInfo.Title,
EnableUPNP: false,
Ports: string(portsStr),
Envs: string(envsStr),
Volumes: string(volumesStr),
Position: true,
NetModel: appInfo.NetworkModel,
Restart: m.Restart,
CpuShares: 50,
Memory: int64(appInfo.MaxMemory),
Devices: string(devicesStr),
Origin: m.Origin,
CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
}
service.MyService.App().SaveContainer(md)

checkSystemApp()
}

// check if the system application is installed
func checkSystemApp() {
list := service.MyService.App().GetSystemAppList()
for _, v := range *list {
if v.Image == "linuxserver/syncthing" {
syncIsExistence = true
if config.SystemConfigInfo.SyncPort != v.Port {
config.SystemConfigInfo.SyncPort = v.Port
}
var paths []model.PathMap
json.Unmarshal([]byte(v.Volumes), &paths)
path := ""
for _, i := range paths {
if i.ContainerPath == "/config" {
path = docker.GetDir(v.CustomId, i.ContainerPath) + "config.xml"
for i := 0; i < 10; i++ {
if file.CheckNotExist(path) {
time.Sleep(1 * time.Second)
} else {
break
}
}
break
}
}
content := file.ReadFullFile(path)
syncConfig := &system_app.SyncConfig{}
xml.Unmarshal(content, &syncConfig)
config.SystemConfigInfo.SyncKey = syncConfig.Key
}
}
if !syncIsExistence {
installSyncthing("44")
}
}
17 changes: 1 addition & 16 deletions route/route.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package route

import (
"fmt"
"net/http"
"net/http/httputil"
"net/url"

"github.com/IceWhaleTech/CasaOS/middleware"
"github.com/IceWhaleTech/CasaOS/pkg/config"
Expand Down Expand Up @@ -41,19 +38,6 @@ func InitRouter() *gin.Engine {
//get user info
r.GET("/v1/user/info", v1.UserInfo)

r.GET("/syncthing/*url", func(c *gin.Context) {
ur := c.Param("url")
fmt.Println(ur)
target := "http://localhost:8384" //最终要访问的服务
remote, err := url.Parse(target)
if err != nil {
fmt.Println(err)
}
proxy := httputil.NewSingleHostReverseProxy(remote)
c.Request.URL.Path = "/" + ur //请求API
proxy.ServeHTTP(c.Writer, c.Request)
})

v1Group := r.Group("/v1")

v1Group.Use(jwt2.JWT(swagHandler))
Expand Down Expand Up @@ -282,6 +266,7 @@ func InitRouter() *gin.Engine {
{
v1SearchGroup.GET("/search", v1.GetSearchList)
}
v1Group.GET("/sync/*url", v1.SyncToSyncthing)
}
return r
}
4 changes: 4 additions & 0 deletions route/v1/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,10 @@ func ContainerUpdateInfo(c *gin.Context) {
var vol model.PathArray
json2.Unmarshal([]byte(appInfo.Volumes), &vol)

for i := 0; i < len(vol); i++ {
vol[i].Path = strings.ReplaceAll(vol[i].Path, "$AppID", appId)
}

var dir model.PathArray
json2.Unmarshal([]byte(appInfo.Devices), &dir)

Expand Down
22 changes: 22 additions & 0 deletions route/v1/sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package v1

import (
"net/http/httputil"
"net/url"

"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/gin-gonic/gin"
)

func SyncToSyncthing(c *gin.Context) {
u := c.Param("url")
target := "http://127.0.0.1:" + config.SystemConfigInfo.SyncPort
remote, err := url.Parse(target)
if err != nil {
return
}
proxy := httputil.NewSingleHostReverseProxy(remote)
c.Request.Header.Add("X-API-Key", config.SystemConfigInfo.SyncKey)
c.Request.URL.Path = u
proxy.ServeHTTP(c.Writer, c.Request)
}
Loading

0 comments on commit f020c11

Please sign in to comment.